[TS Client] Catch exception in onreceive and close connection (#15082)

This commit is contained in:
Brennan 2019-10-17 11:27:03 -07:00 committed by GitHub
parent 418e35c439
commit 23f3a10965
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 3 deletions

View File

@ -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";
}
}

View File

@ -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> {