From b3ee0543aebe0a574abd50a4e78cf130a656482e Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Fri, 1 Nov 2024 01:20:35 -0400 Subject: [PATCH 01/15] Send/receive error details with widgets --- src/embedded.ts | 28 ++++++++++++++++++++++++++++ src/http-api/errors.ts | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/embedded.ts b/src/embedded.ts index a2be6209cdd..1d61d6d5bbb 100644 --- a/src/embedded.ts +++ b/src/embedded.ts @@ -17,6 +17,7 @@ limitations under the License. import { WidgetApi, WidgetApiToWidgetAction, + WidgetApiResponseError, MatrixCapabilities, IWidgetApiRequest, IWidgetApiAcknowledgeResponseData, @@ -45,6 +46,7 @@ import { } from "./client.ts"; import { SyncApi, SyncState } from "./sync.ts"; import { SlidingSyncSdk } from "./sliding-sync-sdk.ts"; +import { MatrixError } from "./http-api/errors.ts"; import { User } from "./models/user.ts"; import { Room } from "./models/room.ts"; import { ToDeviceBatch, ToDevicePayload } from "./models/ToDeviceMessage.ts"; @@ -147,6 +149,26 @@ export class RoomWidgetClient extends MatrixClient { ) { super(opts); + const transportSend = this.widgetApi.transport.send.bind(this.widgetApi.transport); + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + this.widgetApi.transport.send = async (action, data) => { + try { + return await transportSend(action, data); + } catch (error) { + processAndThrow(error); + } + }; + + const transportSendComplete = this.widgetApi.transport.sendComplete.bind(this.widgetApi.transport); + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + this.widgetApi.transport.sendComplete = async (action, data) => { + try { + return await transportSendComplete(action, data); + } catch (error) { + processAndThrow(error); + } + }; + this.widgetApiReady = new Promise((resolve) => this.widgetApi.once("ready", resolve)); // Request capabilities for the functionality this client needs to support @@ -523,3 +545,9 @@ export class RoomWidgetClient extends MatrixClient { } } } + +function processAndThrow(error: unknown): never { + throw error instanceof WidgetApiResponseError && error.data.matrix_api_error + ? MatrixError.fromWidgetApiErrorData(error.data.matrix_api_error) + : error; +} diff --git a/src/http-api/errors.ts b/src/http-api/errors.ts index f80c3fdd8b6..4fa91e3102d 100644 --- a/src/http-api/errors.ts +++ b/src/http-api/errors.ts @@ -14,6 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { IMatrixApiError as IWidgetMatrixError } from "matrix-widget-api"; + import { IUsageLimit } from "../@types/partials.ts"; import { MatrixEvent } from "../models/event.ts"; @@ -131,6 +133,42 @@ export class MatrixError extends HTTPError { } return null; } + + /** + * @returns this error expressed as a {@link IWidgetMatrixError} + * for use by Widget API error responses. + */ + public asWidgetApiErrorData(): IWidgetMatrixError { + const headers: Record = {}; + if (this.httpHeaders) { + for (const [name, value] of this.httpHeaders) { + headers[name] = value; + } + } + return { + http_status: this.httpStatus ?? 400, + http_headers: headers, + url: this.url ?? "", + response: { + errcode: this.errcode ?? "M_UNKNOWN", + error: this.name, + ...this.data, + }, + }; + } + + public static fromWidgetApiErrorData(data: IWidgetMatrixError): MatrixError { + return new MatrixError( + { + errcode: data.response.errcode, + error: data.response.error, + }, + data.http_status, + data.url, + undefined, + new Headers(data.http_headers), + ); + } } /** From a6304ced06fb157d0176297141fa70e0d8d7c9d3 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Fri, 1 Nov 2024 15:28:26 -0400 Subject: [PATCH 02/15] Fix embedded client tests --- spec/unit/embedded.spec.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/unit/embedded.spec.ts b/spec/unit/embedded.spec.ts index dc9952465a6..a8ff7beaf74 100644 --- a/spec/unit/embedded.spec.ts +++ b/spec/unit/embedded.spec.ts @@ -90,7 +90,11 @@ class MockWidgetApi extends EventEmitter { public getTurnServers = jest.fn(() => []); public sendContentLoaded = jest.fn(); - public transport = { reply: jest.fn() }; + public transport = { + reply: jest.fn(), + send: jest.fn(), + sendComplete: jest.fn(), + }; } declare module "../../src/types" { From d13c3d88f6e19510c3c494d09b24c7985e601bb2 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Wed, 6 Nov 2024 11:32:35 -0500 Subject: [PATCH 03/15] Use all properties of error responses --- src/http-api/errors.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/http-api/errors.ts b/src/http-api/errors.ts index 4fa91e3102d..980d4471ed7 100644 --- a/src/http-api/errors.ts +++ b/src/http-api/errors.ts @@ -159,10 +159,7 @@ export class MatrixError extends HTTPError { public static fromWidgetApiErrorData(data: IWidgetMatrixError): MatrixError { return new MatrixError( - { - errcode: data.response.errcode, - error: data.response.error, - }, + data.response, data.http_status, data.url, undefined, From 6b47e220383fdce7439f2abc89b14944dc2e593b Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Wed, 6 Nov 2024 11:34:16 -0500 Subject: [PATCH 04/15] Lint --- src/http-api/errors.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/http-api/errors.ts b/src/http-api/errors.ts index 980d4471ed7..6b377003ce7 100644 --- a/src/http-api/errors.ts +++ b/src/http-api/errors.ts @@ -158,13 +158,7 @@ export class MatrixError extends HTTPError { } public static fromWidgetApiErrorData(data: IWidgetMatrixError): MatrixError { - return new MatrixError( - data.response, - data.http_status, - data.url, - undefined, - new Headers(data.http_headers), - ); + return new MatrixError(data.response, data.http_status, data.url, undefined, new Headers(data.http_headers)); } } From b6f8d1412618353b6e2ccf6cb07b234a14950775 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Thu, 7 Nov 2024 09:28:01 -0500 Subject: [PATCH 05/15] Rewrite ternary expression as if statement --- src/embedded.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/embedded.ts b/src/embedded.ts index 1d61d6d5bbb..615279476da 100644 --- a/src/embedded.ts +++ b/src/embedded.ts @@ -547,7 +547,9 @@ export class RoomWidgetClient extends MatrixClient { } function processAndThrow(error: unknown): never { - throw error instanceof WidgetApiResponseError && error.data.matrix_api_error - ? MatrixError.fromWidgetApiErrorData(error.data.matrix_api_error) - : error; + if (error instanceof WidgetApiResponseError && error.data.matrix_api_error) { + throw MatrixError.fromWidgetApiErrorData(error.data.matrix_api_error); + } else { + throw error; + } } From 156d29a8537e1053307285dedca1caa629b60c3a Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Thu, 7 Nov 2024 11:04:56 -0500 Subject: [PATCH 06/15] Put typehints on overridden functions --- src/embedded.ts | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/embedded.ts b/src/embedded.ts index 615279476da..6ecb29d29f1 100644 --- a/src/embedded.ts +++ b/src/embedded.ts @@ -24,6 +24,10 @@ import { ISendEventToWidgetActionRequest, ISendToDeviceToWidgetActionRequest, ISendEventFromWidgetResponseData, + IWidgetApiRequestData, + WidgetApiAction, + IWidgetApiResponse, + IWidgetApiResponseData, } from "matrix-widget-api"; import { MatrixEvent, IEvent, IContent, EventStatus } from "./models/event.ts"; @@ -150,20 +154,24 @@ export class RoomWidgetClient extends MatrixClient { super(opts); const transportSend = this.widgetApi.transport.send.bind(this.widgetApi.transport); - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - this.widgetApi.transport.send = async (action, data) => { + this.widgetApi.transport.send = async ( + action: WidgetApiAction, + data: T, + ): Promise => { try { - return await transportSend(action, data); + return await transportSend(action, data); } catch (error) { processAndThrow(error); } }; const transportSendComplete = this.widgetApi.transport.sendComplete.bind(this.widgetApi.transport); - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - this.widgetApi.transport.sendComplete = async (action, data) => { + this.widgetApi.transport.sendComplete = async ( + action: WidgetApiAction, + data: T, + ): Promise => { try { - return await transportSendComplete(action, data); + return await transportSendComplete(action, data); } catch (error) { processAndThrow(error); } From fbf6a7ddc575b28cee3a756018a50225528ac84f Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Thu, 7 Nov 2024 13:56:05 -0500 Subject: [PATCH 07/15] Lint --- src/embedded.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/embedded.ts b/src/embedded.ts index 6ecb29d29f1..be03037f974 100644 --- a/src/embedded.ts +++ b/src/embedded.ts @@ -154,7 +154,10 @@ export class RoomWidgetClient extends MatrixClient { super(opts); const transportSend = this.widgetApi.transport.send.bind(this.widgetApi.transport); - this.widgetApi.transport.send = async ( + this.widgetApi.transport.send = async < + T extends IWidgetApiRequestData, + R extends IWidgetApiResponseData = IWidgetApiAcknowledgeResponseData, + >( action: WidgetApiAction, data: T, ): Promise => { From bc08a5dacbb1686a75934885d6eeb2c4b14c8b10 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Fri, 8 Nov 2024 14:20:45 -0500 Subject: [PATCH 08/15] Update matrix-widget-api --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 815fe8cf446..8f6fc95d8a2 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "jwt-decode": "^4.0.0", "loglevel": "^1.7.1", "matrix-events-sdk": "0.0.1", - "matrix-widget-api": "^1.8.2", + "matrix-widget-api": "^1.10.0", "oidc-client-ts": "^3.0.1", "p-retry": "4", "sdp-transform": "^2.14.1", diff --git a/yarn.lock b/yarn.lock index 147a753f154..e999f543286 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4940,10 +4940,10 @@ matrix-mock-request@^2.5.0: dependencies: expect "^28.1.0" -matrix-widget-api@^1.8.2: - version "1.9.0" - resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-1.9.0.tgz#884136b405bd3c56e4ea285095c9e01ec52b6b1f" - integrity sha512-au8mqralNDqrEvaVAkU37bXOb8I9SCe+ACdPk11QWw58FKstVq31q2wRz+qWA6J+42KJ6s1DggWbG/S3fEs3jw== +matrix-widget-api@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-1.10.0.tgz#d31ea073a5871a1fb1a511ef900b0c125a37bf55" + integrity sha512-rkAJ29briYV7TJnfBVLVSKtpeBrBju15JZFSDP6wj8YdbCu1bdmlplJayQ+vYaw1x4fzI49Q+Nz3E85s46sRDw== dependencies: "@types/events" "^3.0.0" events "^3.2.0" From 4e3c3626ceefc8e30da2d48134808d5fa31ae900 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Fri, 8 Nov 2024 14:38:20 -0500 Subject: [PATCH 09/15] Don't @link across packages as gendoc fails when doing so. --- src/http-api/errors.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/http-api/errors.ts b/src/http-api/errors.ts index 6b377003ce7..3c3bbe78a1d 100644 --- a/src/http-api/errors.ts +++ b/src/http-api/errors.ts @@ -135,7 +135,7 @@ export class MatrixError extends HTTPError { } /** - * @returns this error expressed as a {@link IWidgetMatrixError} + * @returns this error expressed as a JSON payload * for use by Widget API error responses. */ public asWidgetApiErrorData(): IWidgetMatrixError { From cdd1608a4682f4552c4f181c9e9a455515a2f5b4 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Fri, 8 Nov 2024 14:38:35 -0500 Subject: [PATCH 10/15] Add a missing docstring --- src/http-api/errors.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/http-api/errors.ts b/src/http-api/errors.ts index 3c3bbe78a1d..4f02ff11b35 100644 --- a/src/http-api/errors.ts +++ b/src/http-api/errors.ts @@ -157,6 +157,10 @@ export class MatrixError extends HTTPError { }; } + /** + * @returns a new {@link MatrixError} from a JSON payload + * received from Widget API error responses. + */ public static fromWidgetApiErrorData(data: IWidgetMatrixError): MatrixError { return new MatrixError(data.response, data.http_status, data.url, undefined, new Headers(data.http_headers)); } From 2cecdd1b73d20ef3cb3daa9ac39cd17cf5bdb3bb Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Fri, 8 Nov 2024 15:30:39 -0500 Subject: [PATCH 11/15] Set widget response error string to correct value --- src/http-api/errors.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/http-api/errors.ts b/src/http-api/errors.ts index 4f02ff11b35..ab02ccfceec 100644 --- a/src/http-api/errors.ts +++ b/src/http-api/errors.ts @@ -151,7 +151,7 @@ export class MatrixError extends HTTPError { url: this.url ?? "", response: { errcode: this.errcode ?? "M_UNKNOWN", - error: this.name, + error: this.data.error ?? "Unknown message", ...this.data, }, }; From b9591c16e6aabb878760088ff80e129b41887550 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Fri, 8 Nov 2024 15:31:42 -0500 Subject: [PATCH 12/15] Test conversion to/from widget error payloads --- spec/unit/http-api/errors.spec.ts | 95 ++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/spec/unit/http-api/errors.spec.ts b/spec/unit/http-api/errors.spec.ts index 6054aad4bb9..bcf3aa45547 100644 --- a/spec/unit/http-api/errors.spec.ts +++ b/spec/unit/http-api/errors.spec.ts @@ -25,8 +25,8 @@ describe("MatrixError", () => { headers = new Headers({ "Content-Type": "application/json" }); }); - function makeMatrixError(httpStatus: number, data: IErrorJson): MatrixError { - return new MatrixError(data, httpStatus, undefined, undefined, headers); + function makeMatrixError(httpStatus: number, data: IErrorJson, url?: string): MatrixError { + return new MatrixError(data, httpStatus, url, undefined, headers); } it("should accept absent retry time from rate-limit error", () => { @@ -95,4 +95,95 @@ describe("MatrixError", () => { const err = makeMatrixError(429, { errcode: "M_LIMIT_EXCEEDED" }); expect(() => err.getRetryAfterMs()).toThrow("integer value is too large"); }); + + describe("can be converted to data compatible with the widget api", () => { + it("from default values", () => { + const matrixError = new MatrixError(); + + const widgetApiErrorData = { + http_status: 400, + http_headers: {}, + url: "", + response: { + errcode: "M_UNKNOWN", + error: "Unknown message", + }, + }; + + expect(matrixError.asWidgetApiErrorData()).toEqual(widgetApiErrorData); + }); + + it("from non-default values", () => { + headers.set("Retry-After", "120"); + const statusCode = 429; + const data = { + errcode: "M_LIMIT_EXCEEDED", + error: "Request is rate-limited.", + retry_after_ms: 120000, + }; + const url = "http://example.net"; + + const matrixError = makeMatrixError(statusCode, data, url); + + const widgetApiErrorData = { + http_status: statusCode, + http_headers: { + "content-type": "application/json", + "retry-after": "120", + }, + url, + response: data, + }; + + expect(matrixError.asWidgetApiErrorData()).toEqual(widgetApiErrorData); + }); + }); + + describe("can be created from data received from the widget api", () => { + it("from minimal data", () => { + const statusCode = 400; + const data = { + errcode: "M_UNKNOWN", + error: "Something went wrong.", + }; + const url = ""; + + const widgetApiErrorData = { + http_status: statusCode, + http_headers: {}, + url, + response: data, + }; + + headers.delete("Content-Type"); + const matrixError = makeMatrixError(statusCode, data, url); + + expect(MatrixError.fromWidgetApiErrorData(widgetApiErrorData)).toEqual(matrixError); + }); + + it("from more data", () => { + const statusCode = 429; + const data = { + errcode: "M_LIMIT_EXCEEDED", + error: "Request is rate-limited.", + retry_after_ms: 120000, + }; + const url = "http://example.net"; + + const widgetApiErrorData = { + http_status: statusCode, + http_headers: { + "content-type": "application/json", + "retry-after": "120", + }, + url, + response: data, + }; + + headers.set("Retry-After", "120"); + const matrixError = makeMatrixError(statusCode, data, url); + + expect(MatrixError.fromWidgetApiErrorData(widgetApiErrorData)).toEqual(matrixError); + }); + }); }); From bdefb0b146ff66621a0f3ae5d83175a4ac85a85c Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Sat, 9 Nov 2024 01:56:33 -0500 Subject: [PATCH 13/15] Test processing errors thrown by widget transport --- spec/unit/embedded.spec.ts | 43 +++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/spec/unit/embedded.spec.ts b/spec/unit/embedded.spec.ts index a8ff7beaf74..02019079011 100644 --- a/spec/unit/embedded.spec.ts +++ b/spec/unit/embedded.spec.ts @@ -30,9 +30,10 @@ import { ITurnServer, IRoomEvent, IOpenIDCredentials, + WidgetApiResponseError, } from "matrix-widget-api"; -import { createRoomWidgetClient, MsgType, UpdateDelayedEventAction } from "../../src/matrix"; +import { createRoomWidgetClient, MatrixError, MsgType, UpdateDelayedEventAction } from "../../src/matrix"; import { MatrixClient, ClientEvent, ITurnServer as IClientTurnServer } from "../../src/client"; import { SyncState } from "../../src/sync"; import { ICapabilities, RoomWidgetClient } from "../../src/embedded"; @@ -191,6 +192,46 @@ describe("RoomWidgetClient", () => { .map((e) => e.getEffectiveEvent()), ).toEqual([event]); }); + + it("handles widget errors with generic error data", async () => { + const error = new Error("failed to send"); + widgetApi.transport.send.mockRejectedValue(error); + + await makeClient({ sendEvent: ["org.matrix.rageshake_request"] }); + widgetApi.sendRoomEvent.mockImplementation(widgetApi.transport.send); + + await expect( + client.sendEvent("!1:example.org", "org.matrix.rageshake_request", { request_id: 123 }) + ).rejects.toThrow(error); + }); + + it("handles widget errors with Matrix API error response data", async () => { + const errorStatusCode = 400; + const errorUrl = "http://example.org"; + const errorData = { + errcode: "M_BAD_JSON", + error: "Invalid body", + }; + + const widgetError = new WidgetApiResponseError("failed to send", { + matrix_api_error: { + http_status: errorStatusCode, + http_headers: {}, + url: errorUrl, + response: errorData, + }, + }); + const matrixError = new MatrixError(errorData, errorStatusCode, errorUrl); + + widgetApi.transport.send.mockRejectedValue(widgetError); + + await makeClient({ sendEvent: ["org.matrix.rageshake_request"] }); + widgetApi.sendRoomEvent.mockImplementation(widgetApi.transport.send); + + await expect( + client.sendEvent("!1:example.org", "org.matrix.rageshake_request", { request_id: 123 }) + ).rejects.toThrow(matrixError); + }); }); describe("delayed events", () => { From 21045a2d98f369356d48aa6932e22d6e98595326 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Sat, 9 Nov 2024 01:59:49 -0500 Subject: [PATCH 14/15] Lint --- spec/unit/embedded.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/unit/embedded.spec.ts b/spec/unit/embedded.spec.ts index 02019079011..dd12fc0f0f9 100644 --- a/spec/unit/embedded.spec.ts +++ b/spec/unit/embedded.spec.ts @@ -201,7 +201,7 @@ describe("RoomWidgetClient", () => { widgetApi.sendRoomEvent.mockImplementation(widgetApi.transport.send); await expect( - client.sendEvent("!1:example.org", "org.matrix.rageshake_request", { request_id: 123 }) + client.sendEvent("!1:example.org", "org.matrix.rageshake_request", { request_id: 123 }), ).rejects.toThrow(error); }); @@ -229,7 +229,7 @@ describe("RoomWidgetClient", () => { widgetApi.sendRoomEvent.mockImplementation(widgetApi.transport.send); await expect( - client.sendEvent("!1:example.org", "org.matrix.rageshake_request", { request_id: 123 }) + client.sendEvent("!1:example.org", "org.matrix.rageshake_request", { request_id: 123 }), ).rejects.toThrow(matrixError); }); }); From ccfcda60538b2d88300afdf7befce69ff63b208f Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Sat, 9 Nov 2024 02:22:41 -0500 Subject: [PATCH 15/15] Test processing errors from transport.sendComplete --- spec/unit/embedded.spec.ts | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/spec/unit/embedded.spec.ts b/spec/unit/embedded.spec.ts index dd12fc0f0f9..b09d3a27097 100644 --- a/spec/unit/embedded.spec.ts +++ b/spec/unit/embedded.spec.ts @@ -643,6 +643,42 @@ describe("RoomWidgetClient", () => { await makeClient({}); expect(await client.getOpenIdToken()).toStrictEqual(testOIDCToken); }); + + it("handles widget errors with generic error data", async () => { + const error = new Error("failed to get token"); + widgetApi.transport.sendComplete.mockRejectedValue(error); + + await makeClient({}); + widgetApi.requestOpenIDConnectToken.mockImplementation(widgetApi.transport.sendComplete as any); + + await expect(client.getOpenIdToken()).rejects.toThrow(error); + }); + + it("handles widget errors with Matrix API error response data", async () => { + const errorStatusCode = 400; + const errorUrl = "http://example.org"; + const errorData = { + errcode: "M_UNKNOWN", + error: "Bad request", + }; + + const widgetError = new WidgetApiResponseError("failed to get token", { + matrix_api_error: { + http_status: errorStatusCode, + http_headers: {}, + url: errorUrl, + response: errorData, + }, + }); + const matrixError = new MatrixError(errorData, errorStatusCode, errorUrl); + + widgetApi.transport.sendComplete.mockRejectedValue(widgetError); + + await makeClient({}); + widgetApi.requestOpenIDConnectToken.mockImplementation(widgetApi.transport.sendComplete as any); + + await expect(client.getOpenIdToken()).rejects.toThrow(matrixError); + }); }); it("gets TURN servers", async () => {