[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) => {
|
||||
this.logger.log(LogLevel.Trace, `(WebSockets transport) data received. ${getDataDetail(message.data, this.logMessageContent)}.`);
|
||||
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();
|
||||
}
|
||||
|
||||
private close(event?: CloseEvent): void {
|
||||
private close(event?: CloseEvent | Error): void {
|
||||
// webSocket will be null if the transport did not start successfully
|
||||
this.logger.log(LogLevel.Trace, "(WebSockets transport) socket closed.");
|
||||
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}).`));
|
||||
} else if (event instanceof Error) {
|
||||
this.onclose(event);
|
||||
} else {
|
||||
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");
|
||||
});
|
||||
});
|
||||
|
||||
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> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue