Skip to content

Commit dfd7fdd

Browse files
elliotttJakeChampion
authored andcommitted
Reject promises for requests that fail
1 parent 65aad5d commit dfd7fdd

File tree

3 files changed

+75
-14
lines changed

3 files changed

+75
-14
lines changed

c-dependencies/js-compute-runtime/js-compute-builtins.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ bool isWizening() { return execution_mode == Mode::PreWizening; }
6565

6666
void markWizeningAsFinished() { execution_mode = Mode::PostWizening; }
6767

68+
namespace Request {
69+
JSObject *response_promise(JSObject *obj);
70+
}
71+
6872
typedef bool InternalMethod(JSContext *cx, HandleObject receiver, HandleValue extra, CallArgs args);
6973
template <InternalMethod fun> bool internal_method(JSContext *cx, unsigned argc, Value *vp) {
7074
CallArgs args = CallArgsFromVp(argc, vp);
@@ -1377,6 +1381,22 @@ bool body_reader_then_handler(JSContext *cx, HandleObject body_owner, HandleValu
13771381
fprintf(stderr, "Error: read operation on body ReadableStream didn't respond with a "
13781382
"Uint8Array. Received value: ");
13791383
dump_value(cx, val, stderr);
1384+
1385+
// reject the request promise
1386+
if (Request::is_instance(body_owner)) {
1387+
RootedObject response_promise(cx, Request::response_promise(body_owner));
1388+
RootedValue exn(cx);
1389+
1390+
// TODO: this should be a TypeError, but I'm not sure how to make that work
1391+
JS_ReportErrorUTF8(cx, "TypeError");
1392+
if (!JS_GetPendingException(cx, &exn)) {
1393+
return false;
1394+
}
1395+
JS_ClearPendingException(cx);
1396+
1397+
return JS::RejectPromise(cx, response_promise, exn);
1398+
}
1399+
13801400
return false;
13811401
}
13821402

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,46 @@
11
addEventListener("fetch", event => event.respondWith(handleRequest(event.request)));
22

33
async function handleRequest(req: Request) {
4-
let [body1, _body2] = req.body.tee();
54

6-
// Regression test for making requests whose bodies are streams that result
7-
// from a `tee`. The bug this is guarding against is where we were eagerly
8-
// placing the request into the pending queue, even though its body stream had
9-
// not been closed yet. This resulted in deadlock when we called
10-
// `pending_req_select`, as we were waiting on an http request whose body had
11-
// not been closed.
12-
let res = fetch(new Request(req.url, {
13-
body: body1,
14-
headers: req.headers,
15-
method: req.method,
16-
backend: "TheOrigin"
17-
}));
5+
if (req.url.endsWith("/tee")) {
6+
let [body1, _body2] = req.body.tee();
187

19-
return res;
8+
// Regression test for making requests whose bodies are streams that result
9+
// from a `tee`. The bug this is guarding against is where we were eagerly
10+
// placing the request into the pending queue, even though its body stream had
11+
// not been closed yet. This resulted in deadlock when we called
12+
// `pending_req_select`, as we were waiting on an http request whose body had
13+
// not been closed.
14+
let res = fetch(new Request(req.url, {
15+
body: body1,
16+
headers: req.headers,
17+
method: req.method,
18+
backend: "TheOrigin"
19+
}));
20+
21+
return res;
22+
}
23+
24+
if (req.url.endsWith("/error")) {
25+
console.log(req.method);
26+
let res = fetch(req.url, {
27+
method: "POST",
28+
body: new ReadableStream({
29+
start: controller => {
30+
controller.enqueue("Test");
31+
controller.close();
32+
}
33+
}),
34+
backend: "TheOrigin",
35+
});
36+
37+
return res
38+
.then(_ => new Response("Error wasn't raised"))
39+
.catch(err => {
40+
console.log(err.toString());
41+
return new Response(err.toString());
42+
});
43+
}
44+
45+
return new Response("");
2046
}

integration-tests/js-compute/fixtures/tee/tests.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,20 @@
1313
"status": 200,
1414
"body": "hello world!"
1515
}
16+
},
17+
18+
"GET /error": {
19+
"environments": ["viceroy", "c@e"],
20+
"downstream_request": {
21+
"method": "GET",
22+
"pathname": "/error",
23+
"headers": {
24+
"Content-Type": "application/json"
25+
}
26+
},
27+
"downstream_response": {
28+
"status": 200,
29+
"body": "Error: TypeError"
30+
}
1631
}
1732
}

0 commit comments

Comments
 (0)