[TS Client] Catch exception in onreceive and close connection (#15082)
This commit is contained in:
parent
418e35c439
commit
23f3a10965
|
|
@ -96,7 +96,12 @@ export class WebSocketTransport implements ITransport {
|
||||||
webSocket.onmessage = (message: MessageEvent) => {
|
webSocket.onmessage = (message: MessageEvent) => {
|
||||||
this.logger.log(LogLevel.Trace, `(WebSockets transport) data received. ${getDataDetail(message.data, this.logMessageContent)}.`);
|
this.logger.log(LogLevel.Trace, `(WebSockets transport) data received. ${getDataDetail(message.data, this.logMessageContent)}.`);
|
||||||
if (this.onreceive) {
|
if (this.onreceive) {
|
||||||
this.onreceive(message.data);
|
try {
|
||||||
|
this.onreceive(message.data);
|
||||||
|
} catch (error) {
|
||||||
|
this.close(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -131,15 +136,21 @@ export class WebSocketTransport implements ITransport {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
private close(event?: CloseEvent): void {
|
private close(event?: CloseEvent | Error): void {
|
||||||
// webSocket will be null if the transport did not start successfully
|
// webSocket will be null if the transport did not start successfully
|
||||||
this.logger.log(LogLevel.Trace, "(WebSockets transport) socket closed.");
|
this.logger.log(LogLevel.Trace, "(WebSockets transport) socket closed.");
|
||||||
if (this.onclose) {
|
if (this.onclose) {
|
||||||
if (event && (event.wasClean === false || event.code !== 1000)) {
|
if (this.isCloseEvent(event) && (event.wasClean === false || event.code !== 1000)) {
|
||||||
this.onclose(new Error(`WebSocket closed with status code: ${event.code} (${event.reason}).`));
|
this.onclose(new Error(`WebSocket closed with status code: ${event.code} (${event.reason}).`));
|
||||||
|
} else if (event instanceof Error) {
|
||||||
|
this.onclose(event);
|
||||||
} else {
|
} else {
|
||||||
this.onclose();
|
this.onclose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isCloseEvent(event?: any): event is CloseEvent {
|
||||||
|
return event && typeof event.wasClean === "boolean" && typeof event.code === "number";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -229,6 +229,36 @@ describe("WebSocketTransport", () => {
|
||||||
.toBe("WebSocket is not in the OPEN state");
|
.toBe("WebSocket is not in the OPEN state");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("is closed from 'onreceive' callback throwing", async () => {
|
||||||
|
await VerifyLogger.run(async (logger) => {
|
||||||
|
(global as any).ErrorEvent = TestEvent;
|
||||||
|
const webSocket = await createAndStartWebSocket(logger);
|
||||||
|
|
||||||
|
let closeCalled: boolean = false;
|
||||||
|
let error: Error;
|
||||||
|
webSocket.onclose = (e) => {
|
||||||
|
closeCalled = true;
|
||||||
|
error = e!;
|
||||||
|
};
|
||||||
|
|
||||||
|
const receiveError = new Error("callback error");
|
||||||
|
webSocket.onreceive = (data) => {
|
||||||
|
throw receiveError;
|
||||||
|
};
|
||||||
|
|
||||||
|
const message = new TestMessageEvent();
|
||||||
|
message.data = "receive data";
|
||||||
|
TestWebSocket.webSocket.onmessage(message);
|
||||||
|
|
||||||
|
expect(closeCalled).toBe(true);
|
||||||
|
expect(error!).toBe(receiveError);
|
||||||
|
|
||||||
|
await expect(webSocket.send(""))
|
||||||
|
.rejects
|
||||||
|
.toBe("WebSocket is not in the OPEN state");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
async function createAndStartWebSocket(logger: ILogger, url?: string, accessTokenFactory?: (() => string | Promise<string>), format?: TransferFormat): Promise<WebSocketTransport> {
|
async function createAndStartWebSocket(logger: ILogger, url?: string, accessTokenFactory?: (() => string | Promise<string>), format?: TransferFormat): Promise<WebSocketTransport> {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue