Skip to content

Commit

Permalink
fix(google-pubsub): Wrap Google SDK errors with helpful errors
Browse files Browse the repository at this point in the history
  • Loading branch information
gnarea committed Oct 12, 2023
1 parent 4fda6fa commit d279562
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 3 deletions.
19 changes: 17 additions & 2 deletions src/lib/googlePubSub.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { jest } from '@jest/globals';
import type { CloudEvent } from 'cloudevents';
import { formatISO, getUnixTime, setMilliseconds } from 'date-fns';

import { mockSpy } from '../testUtils/jest.js';
import { getPromiseRejection, mockSpy } from '../testUtils/jest.js';
import { GOOGLE_PUBSUB_TOPIC, EVENT } from '../testUtils/stubs.js';
import { jsonSerialise } from '../testUtils/json.js';

const mockPublishMessage = mockSpy(jest.fn<any>().mockResolvedValue(undefined));
const mockPublishMessage = mockSpy(jest.fn<any>());
const mockTopic = jest.fn<any>().mockReturnValue({ publishMessage: mockPublishMessage });
jest.unstable_mockModule('@google-cloud/pubsub', () => ({
// eslint-disable-next-line @typescript-eslint/naming-convention
Expand Down Expand Up @@ -209,6 +209,21 @@ describe('makeGooglePubSubEmitter', () => {

expect(mockTopic).toHaveBeenCalledWith(GOOGLE_PUBSUB_TOPIC);
});

test('Publish errors should be wrapped', async () => {
const error = new Error('Publish error');
mockPublishMessage.mockRejectedValue(error);

const errorWrapper = await getPromiseRejection(
async () => makeGooglePubSubEmitter(GOOGLE_PUBSUB_TOPIC)(EVENT),
Error,
);

expect(errorWrapper.message).toBe(
`Failed to publish message to Google PubSub topic "${GOOGLE_PUBSUB_TOPIC}"`,
);
expect(errorWrapper.cause).toBe(error);
});
});

describe('convertGooglePubSubMessage', () => {
Expand Down
9 changes: 8 additions & 1 deletion src/lib/googlePubSub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,14 @@ export function makeGooglePubSubEmitter(topicName: string): EmitterFunction {
return async (event) => {
const topic = CLIENT.topic(topicName);
const message = convertEventToMessage(event);
await topic.publishMessage(message);
try {
await topic.publishMessage(message);
} catch (err) {
// Google SDK exceptions are utterly meaningless
throw new Error(`Failed to publish message to Google PubSub topic "${topicName}"`, {
cause: err,
});
}
};
}

Expand Down
15 changes: 15 additions & 0 deletions src/testUtils/jest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,18 @@ export function mockSpy<
export function getMockInstance(mockedObject: any): jest.MockInstance<any, any> {
return mockedObject as unknown as jest.MockInstance<any, any>;
}

export async function getPromiseRejection<ErrorType extends Error>(
rejectingFunction: () => Promise<unknown>,
expectedErrorType: new () => ErrorType,
): Promise<ErrorType> {
let error: ErrorType | undefined;
try {
await rejectingFunction();
} catch (err) {
error = err as ErrorType;
}

expect(error).toBeInstanceOf(expectedErrorType);
return error!;
}

0 comments on commit d279562

Please sign in to comment.