summaryrefslogtreecommitdiff
path: root/runtime/js
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/js')
-rw-r--r--runtime/js/40_http.js26
1 files changed, 23 insertions, 3 deletions
diff --git a/runtime/js/40_http.js b/runtime/js/40_http.js
index eb3c58a63..eb4d214ca 100644
--- a/runtime/js/40_http.js
+++ b/runtime/js/40_http.js
@@ -14,6 +14,8 @@
return new HttpConn(rid);
}
+ const connErrorSymbol = Symbol("connError");
+
class HttpConn {
#rid = 0;
@@ -35,10 +37,16 @@
this.#rid,
);
} catch (error) {
+ // A connection error seen here would cause disrupted responses to throw
+ // a generic `BadResource` error. Instead store this error and replace
+ // those with it.
+ this[connErrorSymbol] = error;
if (error instanceof errors.BadResource) {
return null;
} else if (error instanceof errors.Interrupted) {
return null;
+ } else if (error.message.includes("connection closed")) {
+ return null;
}
throw error;
}
@@ -66,7 +74,7 @@
);
const request = fromInnerRequest(innerRequest, "immutable");
- const respondWith = createRespondWith(responseSenderRid, this.#rid);
+ const respondWith = createRespondWith(this, responseSenderRid);
return { request, respondWith };
}
@@ -97,7 +105,7 @@
);
}
- function createRespondWith(responseSenderRid) {
+ function createRespondWith(httpConn, responseSenderRid) {
return async function respondWith(resp) {
if (resp instanceof Promise) {
resp = await resp;
@@ -145,6 +153,11 @@
innerResp.headerList,
], respBody instanceof Uint8Array ? respBody : null);
} catch (error) {
+ const connError = httpConn[connErrorSymbol];
+ if (error instanceof errors.BadResource && connError != null) {
+ // deno-lint-ignore no-ex-assign
+ error = new connError.constructor(connError.message);
+ }
if (respBody !== null && respBody instanceof ReadableStream) {
await respBody.cancel(error);
}
@@ -173,6 +186,11 @@
value,
);
} catch (error) {
+ const connError = httpConn[connErrorSymbol];
+ if (error instanceof errors.BadResource && connError != null) {
+ // deno-lint-ignore no-ex-assign
+ error = new connError.constructor(connError.message);
+ }
await reader.cancel(error);
throw error;
}
@@ -180,7 +198,9 @@
} finally {
// Once all chunks are sent, and the request body is closed, we can
// close the response body.
- await Deno.core.opAsync("op_http_response_close", responseBodyRid);
+ try {
+ await Deno.core.opAsync("op_http_response_close", responseBodyRid);
+ } catch { /* pass */ }
}
}
};