1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 01:03:35 +00:00

[EC-598] feat: add ability to throw errors across messenger

This commit is contained in:
Andreas Coroiu
2023-01-27 16:02:13 +01:00
parent 3c5900250d
commit 547c29970d
3 changed files with 50 additions and 21 deletions

View File

@@ -14,6 +14,7 @@ export enum MessageType {
CredentialGetResponse,
AbortRequest,
AbortResponse,
ErrorResponse,
}
export type CredentialCreationRequest = {
@@ -43,6 +44,11 @@ export type AbortRequest = {
abortedRequestId: string;
};
export type ErrorResponse = {
type: MessageType.ErrorResponse;
error: string;
};
export type AbortResponse = {
type: MessageType.AbortResponse;
abortedRequestId: string;
@@ -54,4 +60,5 @@ export type Message =
| CredentialGetRequest
| CredentialGetResponse
| AbortRequest
| AbortResponse;
| AbortResponse
| ErrorResponse;

View File

@@ -44,6 +44,17 @@ describe("Messenger", () => {
expect(returned).toMatchObject(response);
});
it("should throw error from B when sending request from A that fails", async () => {
const request = createRequest();
const error = new Error("Test error");
const requestPromise = messengerA.request(request);
const received = handlerB.recieve();
received[0].reject(error);
await expect(requestPromise).rejects.toThrow();
});
it("should deliver abort signal to B when requesting abort", () => {
const abortController = new AbortController();
messengerA.request(createRequest(), abortController);
@@ -53,15 +64,6 @@ describe("Messenger", () => {
expect(received[0].abortController.signal.aborted).toBe(true);
});
it.skip("should abort request and throw error when abort is requested from A", () => {
const abortController = new AbortController();
const requestPromise = messengerA.request(createRequest(), abortController);
abortController.abort();
expect(requestPromise).toThrow();
});
});
type TestMessage = Message & { testId: string };
@@ -105,6 +107,7 @@ class TestMessageHandler {
private recievedMessages: {
message: TestMessage;
respond: (response: TestMessage) => void;
reject: (error: Error) => void;
abortController?: AbortController;
}[] = [];
@@ -115,6 +118,7 @@ class TestMessageHandler {
message,
abortController,
respond: (response) => resolve(response),
reject: (error) => reject(error),
});
});
}

View File

@@ -49,15 +49,26 @@ export class Messenger {
const abortController = new AbortController();
this.abortControllers.set(message.metadata.requestId, abortController);
const handlerResponse = await this.handler(message, abortController);
this.abortControllers.delete(message.metadata.requestId);
if (handlerResponse === undefined) {
return;
try {
const handlerResponse = await this.handler(message, abortController);
if (handlerResponse === undefined) {
return;
}
const metadata: Metadata = { requestId: message.metadata.requestId };
this.channel.postMessage({ ...handlerResponse, metadata });
} catch (error) {
const metadata: Metadata = { requestId: message.metadata.requestId };
this.channel.postMessage({
type: MessageType.ErrorResponse,
metadata,
error: JSON.stringify(error, Object.getOwnPropertyNames(error)),
});
} finally {
this.abortControllers.delete(message.metadata.requestId);
}
const metadata: Metadata = { requestId: message.metadata.requestId };
this.channel.postMessage({ ...handlerResponse, metadata });
})
)
.subscribe();
@@ -71,7 +82,7 @@ export class Messenger {
});
}
request(request: Message, abortController?: AbortController): Promise<Message> {
async request(request: Message, abortController?: AbortController): Promise<Message> {
const requestId = Date.now().toString();
const metadata: Metadata = { requestId };
@@ -93,8 +104,15 @@ export class Messenger {
this.channel.postMessage({ ...request, metadata });
return promise.finally(() =>
abortController?.signal.removeEventListener("abort", abortListener)
);
const response = await promise;
abortController?.signal.removeEventListener("abort", abortListener);
if (response.type === MessageType.ErrorResponse) {
const error = new Error();
Object.assign(error, JSON.parse(response.error));
throw error;
}
return response;
}
}