summaryrefslogtreecommitdiff
path: root/ext/websocket/02_websocketstream.js
diff options
context:
space:
mode:
authorAsher Gomez <ashersaupingomez@gmail.com>2024-04-09 04:46:53 +1000
committerGitHub <noreply@github.com>2024-04-08 20:46:53 +0200
commit03b84197a0ca181443ef06d870100b2157e1f1b8 (patch)
treebf052e96513fa2d862b35963749b528a4491b08e /ext/websocket/02_websocketstream.js
parent3c346c8ea6aa888475c19d512ddd4c247c00b1ea (diff)
chore: update WPT (#23111)
Should fix some of the current issues with the `wpt_epoch` workflow. See https://github.com/denoland/deno/actions/runs/8460701853/job/23179358486 --------- Co-authored-by: crowlkats <crowlkats@toaxl.com> Co-authored-by: Bartek IwaƄczuk <biwanczuk@gmail.com>
Diffstat (limited to 'ext/websocket/02_websocketstream.js')
-rw-r--r--ext/websocket/02_websocketstream.js180
1 files changed, 130 insertions, 50 deletions
diff --git a/ext/websocket/02_websocketstream.js b/ext/websocket/02_websocketstream.js
index 4eafac88b..01aef45d3 100644
--- a/ext/websocket/02_websocketstream.js
+++ b/ext/websocket/02_websocketstream.js
@@ -18,7 +18,6 @@ const {
ArrayPrototypeJoin,
ArrayPrototypeMap,
DateNow,
- Error,
ObjectPrototypeIsPrototypeOf,
PromisePrototypeCatch,
PromisePrototypeThen,
@@ -68,8 +67,12 @@ webidl.converters.WebSocketCloseInfo = webidl.createDictionaryConverter(
"WebSocketCloseInfo",
[
{
- key: "code",
- converter: webidl.converters["unsigned short"],
+ key: "closeCode",
+ converter: (V, prefix, context, opts) =>
+ webidl.converters["unsigned short"](V, prefix, context, {
+ ...opts,
+ enforceRange: true,
+ }),
},
{
key: "reason",
@@ -189,20 +192,14 @@ class WebSocketStream {
}
})(),
() => {
- const err = new DOMException(
- "Closed while connecting",
- "NetworkError",
- );
+ const err = new WebSocketError("Closed while connecting");
this[_opened].reject(err);
this[_closed].reject(err);
},
);
},
() => {
- const err = new DOMException(
- "Closed while connecting",
- "NetworkError",
- );
+ const err = new WebSocketError("Closed while connecting");
this[_opened].reject(err);
this[_closed].reject(err);
},
@@ -225,17 +222,26 @@ class WebSocketStream {
);
}
},
- close: async (reason) => {
- try {
- this.close(reason?.code !== undefined ? reason : {});
- } catch (_) {
- this.close();
- }
+ close: async () => {
+ this.close();
await this.closed;
},
abort: async (reason) => {
+ let closeCode = null;
+ let reasonString = "";
+
+ if (
+ ObjectPrototypeIsPrototypeOf(WebSocketErrorPrototype, reason)
+ ) {
+ closeCode = reason.closeCode;
+ reasonString = reason.reason;
+ }
+
try {
- this.close(reason?.code !== undefined ? reason : {});
+ this.close({
+ closeCode,
+ reason: reasonString,
+ });
} catch (_) {
this.close();
}
@@ -261,7 +267,7 @@ class WebSocketStream {
}
case 3: {
/* error */
- const err = new Error(op_ws_get_error(this[_rid]));
+ const err = new WebSocketError(op_ws_get_error(this[_rid]));
this[_closed].reject(err);
controller.error(err);
core.tryClose(this[_rid]);
@@ -269,7 +275,7 @@ class WebSocketStream {
}
case 1005: {
/* closed */
- this[_closed].resolve({ code: 1005, reason: "" });
+ this[_closed].resolve({ closeCode: 1005, reason: "" });
core.tryClose(this[_rid]);
break;
}
@@ -277,7 +283,7 @@ class WebSocketStream {
/* close */
const reason = op_ws_get_error(this[_rid]);
this[_closed].resolve({
- code: kind,
+ closeCode: kind,
reason,
});
core.tryClose(this[_rid]);
@@ -297,7 +303,7 @@ class WebSocketStream {
}
const error = op_ws_get_error(this[_rid]);
- this[_closed].reject(new Error(error));
+ this[_closed].reject(new WebSocketError(error));
core.tryClose(this[_rid]);
}
};
@@ -327,8 +333,21 @@ class WebSocketStream {
},
pull,
cancel: async (reason) => {
+ let closeCode = null;
+ let reasonString = "";
+
+ if (
+ ObjectPrototypeIsPrototypeOf(WebSocketErrorPrototype, reason)
+ ) {
+ closeCode = reason.closeCode;
+ reasonString = reason.reason;
+ }
+
try {
- this.close(reason?.code !== undefined ? reason : {});
+ this.close({
+ closeCode,
+ reason: reasonString,
+ });
} catch (_) {
this.close();
}
@@ -350,6 +369,7 @@ class WebSocketStream {
err = options.signal.reason;
} else {
core.tryClose(cancelRid);
+ err = new WebSocketError(err.message);
}
this[_opened].reject(err);
this[_closed].reject(err);
@@ -380,38 +400,17 @@ class WebSocketStream {
"Argument 1",
);
- if (
- closeInfo.code &&
- !(closeInfo.code === 1000 ||
- (3000 <= closeInfo.code && closeInfo.code < 5000))
- ) {
- throw new DOMException(
- "The close code must be either 1000 or in the range of 3000 to 4999.",
- "InvalidAccessError",
- );
- }
+ validateCloseCodeAndReason(closeInfo);
- const encoder = new TextEncoder();
- if (
- closeInfo.reason &&
- TypedArrayPrototypeGetByteLength(encoder.encode(closeInfo.reason)) > 123
- ) {
- throw new DOMException(
- "The close reason may not be longer than 123 bytes.",
- "SyntaxError",
- );
- }
-
- let code = closeInfo.code;
- if (closeInfo.reason && code === undefined) {
- code = 1000;
+ if (closeInfo.reason && closeInfo.closeCode === null) {
+ closeInfo.closeCode = 1000;
}
if (this[_opened].state === "pending") {
this[_earlyClose] = true;
} else if (this[_closed].state === "pending") {
PromisePrototypeThen(
- op_ws_close(this[_rid], code, closeInfo.reason),
+ op_ws_close(this[_rid], closeInfo.closeCode, closeInfo.reason),
() => {
setTimeout(() => {
this[_closeSent].resolve(DateNow());
@@ -419,6 +418,7 @@ class WebSocketStream {
},
(err) => {
this[_rid] && core.tryClose(this[_rid]);
+ err = new WebSocketError(err.message);
this[_closed].reject(err);
},
);
@@ -440,7 +440,87 @@ class WebSocketStream {
);
}
}
-
const WebSocketStreamPrototype = WebSocketStream.prototype;
-export { WebSocketStream };
+function validateCloseCodeAndReason(closeInfo) {
+ if (!closeInfo.closeCode) {
+ closeInfo.closeCode = null;
+ }
+
+ if (
+ closeInfo.closeCode &&
+ !(closeInfo.closeCode === 1000 ||
+ (3000 <= closeInfo.closeCode && closeInfo.closeCode < 5000))
+ ) {
+ throw new DOMException(
+ "The close code must be either 1000 or in the range of 3000 to 4999.",
+ "InvalidAccessError",
+ );
+ }
+
+ const encoder = new TextEncoder();
+ if (
+ closeInfo.reason &&
+ TypedArrayPrototypeGetByteLength(encoder.encode(closeInfo.reason)) > 123
+ ) {
+ throw new DOMException(
+ "The close reason may not be longer than 123 bytes.",
+ "SyntaxError",
+ );
+ }
+}
+
+class WebSocketError extends DOMException {
+ #closeCode;
+ #reason;
+
+ constructor(message = "", init = {}) {
+ super(message, "WebSocketError");
+ this[webidl.brand] = webidl.brand;
+
+ init = webidl.converters["WebSocketCloseInfo"](
+ init,
+ "Failed to construct 'WebSocketError'",
+ "Argument 2",
+ );
+
+ validateCloseCodeAndReason(init);
+
+ if (init.reason && init.closeCode === null) {
+ init.closeCode = 1000;
+ }
+
+ this.#closeCode = init.closeCode;
+ this.#reason = init.reason;
+ }
+
+ get closeCode() {
+ webidl.assertBranded(this, WebSocketErrorPrototype);
+ return this.#closeCode;
+ }
+
+ get reason() {
+ webidl.assertBranded(this, WebSocketErrorPrototype);
+ return this.#reason;
+ }
+
+ [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) {
+ return inspect(
+ createFilteredInspectProxy({
+ object: this,
+ evaluate: ObjectPrototypeIsPrototypeOf(WebSocketErrorPrototype, this),
+ keys: [
+ "message",
+ "name",
+ "closeCode",
+ "reason",
+ ],
+ }),
+ inspectOptions,
+ );
+ }
+}
+webidl.configureInterface(WebSocketError);
+const WebSocketErrorPrototype = WebSocketError.prototype;
+
+export { WebSocketError, WebSocketStream };