fix onerror bugs

This commit is contained in:
Spencer Pogorzelski 2023-08-14 14:29:45 -07:00
parent feaac8d6c3
commit 358075f84b
3 changed files with 27 additions and 9 deletions

View file

@ -71,11 +71,21 @@ export class AdriftBareClient extends Client {
let initalCloseHappened = false;
ws.addEventListener("close", (e) => {
if (!initalCloseHappened) {
// we can freely mess with the fake readyState here because there is no
// readyStateChange listener for WebSockets
onReadyState(WebSocket.CONNECTING);
e.stopImmediatePropagation();
initalCloseHappened = true;
}
});
let initialErrorHappened = false;
ws.addEventListener("error", (e) => {
if (!initialErrorHappened) {
onReadyState(WebSocket.CONNECTING);
e.stopImmediatePropagation();
initialErrorHappened = true;
}
});
let { send, close } = this.connection.wsconnect(
remote,
@ -95,6 +105,7 @@ export class AdriftBareClient extends Client {
);
},
(message: string) => {
console.log({ message });
ws.dispatchEvent(new ErrorEvent("error", { message }));
}
);

View file

@ -12,6 +12,7 @@ import {
} from "protocol";
type OpenWSMeta = {
onopen: () => void;
onclose: (code: number, reason: string, wasClean: boolean) => void;
onmessage: (data: any) => void;
onerror: (message: string) => void;
@ -20,7 +21,7 @@ type OpenWSMeta = {
export class Connection {
requestCallbacks: Record<number, Function> = {};
openRequestStreams: Record<number, ReadableStreamDefaultController<any>> = {};
openingSockets: Record<number, { onopen: () => void; rest: OpenWSMeta }> = {};
openingSockets: Record<number, OpenWSMeta> = {};
openSockets: Record<number, OpenWSMeta> = {};
counter: number = 0;
@ -47,6 +48,7 @@ export class Connection {
const msgText = () => new TextDecoder().decode(data.slice(cursor));
const msgJSON = () => JSON.parse(msgText());
console.log({ requestType });
switch (requestType) {
case S2CRequestTypes.HTTPResponseStart:
const payload = msgJSON();
@ -77,10 +79,10 @@ export class Connection {
break;
case S2CRequestTypes.WSOpen:
const { onopen, rest } = this.openingSockets[requestID];
const socketMeta = this.openingSockets[requestID];
delete this.openingSockets[requestID];
this.openSockets[requestID] = rest;
onopen();
this.openSockets[requestID] = socketMeta;
setTimeout(() => socketMeta.onopen());
break;
case S2CRequestTypes.WSDataText: {
@ -98,7 +100,8 @@ export class Connection {
}
case S2CRequestTypes.WSClose: {
const socketMeta = this.openSockets[requestID];
const socketMeta =
this.openingSockets[requestID] || this.openSockets[requestID];
if (!socketMeta) return;
const payload: WSClosePayload = msgJSON();
setTimeout(() =>
@ -108,16 +111,18 @@ export class Connection {
"wasClean" in payload ? Boolean(payload.wasClean) : false
)
);
delete this.openingSockets[requestID];
delete this.openSockets[requestID];
break;
}
case S2CRequestTypes.WSError: {
const socketMeta = this.openSockets[requestID];
const socketMeta =
this.openingSockets[requestID] || this.openSockets[requestID];
if (!socketMeta) return;
const payload: WSErrorPayload = msgJSON();
setTimeout(() => socketMeta.onerror(payload.message));
setTimeout(() => socketMeta.onclose(1006, "", false));
// don't delete socket entries because server will send close after this
break;
}
@ -187,7 +192,9 @@ export class Connection {
// this can't be async, just call onopen when opened
this.openingSockets[seq] = {
onopen,
rest: { onmessage, onclose, onerror },
onmessage,
onclose,
onerror,
};
return {

View file

@ -246,8 +246,8 @@ export class AdriftServer {
const ws = (this.sockets[seq] = new WebSocket(payload.url));
ws.binaryType = "arraybuffer";
ws.onerror = (e) => {
// WSError implies close with code 1006, reason "" and wasClean false
this.sendWSError(seq, { message: e.message });
// onclose will be called after this with code 1006, reason "" and wasClean false
};
ws.onopen = () => {
this.sendWSOpen(seq);