From 8b3d19a325ad0a098da1fb3a2c2c63c87f8ad360 Mon Sep 17 00:00:00 2001 From: Sebastian Alex Date: Tue, 29 Oct 2024 12:37:16 +0100 Subject: [PATCH] nestjs: fix skipIfClientUndefined not working in BacktraceModule --- packages/nestjs/src/backtrace.module.ts | 7 ++- .../nestjs/tests/backtrace.handler.spec.ts | 57 ++++++++++++++++++- .../nestjs/tests/backtrace.module.spec.ts | 14 +++++ 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/packages/nestjs/src/backtrace.module.ts b/packages/nestjs/src/backtrace.module.ts index 7f4e315b..1c869c7f 100644 --- a/packages/nestjs/src/backtrace.module.ts +++ b/packages/nestjs/src/backtrace.module.ts @@ -40,7 +40,12 @@ const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } = new ConfigurableModule (instanceOrOptions instanceof BacktraceClient ? instanceOrOptions : instanceOrOptions?.client) ?? BacktraceClient.instance; - if (!instance) { + const skipIfClientUndefined = + instanceOrOptions instanceof BacktraceClient + ? false + : instanceOrOptions?.options?.skipIfClientUndefined; + + if (!instance && !skipIfClientUndefined) { throw new Error( 'Backtrace instance is not available. Initialize it first, or pass it into the module using register/registerAsync.', ); diff --git a/packages/nestjs/tests/backtrace.handler.spec.ts b/packages/nestjs/tests/backtrace.handler.spec.ts index 22d0a927..06e3cb3b 100644 --- a/packages/nestjs/tests/backtrace.handler.spec.ts +++ b/packages/nestjs/tests/backtrace.handler.spec.ts @@ -39,7 +39,11 @@ describe('BacktraceInterceptor', () => { class Filter extends BaseExceptionFilter { catch(exception: unknown, host: ArgumentsHost): void { - handler.handleException(exception, host); + try { + handler.handleException(exception, host); + } catch (err) { + // Do nothing + } super.catch(exception, host); } } @@ -122,6 +126,57 @@ describe('BacktraceInterceptor', () => { expect(send).not.toBeCalled(); }); + it('should throw if client is uninitialized', async () => { + const error = new Error('foo'); + + @Controller() + class TestController { + @Get('error') + public error() { + throw error; + } + } + + const interceptor = new BacktraceExceptionHandler({}); + const handleException = jest.spyOn(interceptor, 'handleException'); + + const { app } = await createAppWithHandler(interceptor, TestController); + + await app.init(); + await request(app.getHttpServer()).get('/error').expect(500); + + const result = handleException.mock.results[0]; + expect(result.type).toEqual('throw'); + expect(result.value).toBeInstanceOf(Error); + expect(result.value.message).toBe('Backtrace instance is unavailable. Initialize the client first.'); + }); + + it('should not throw if client is uninitialized and skipIfClientUndefined is true', async () => { + const error = new Error('foo'); + + @Controller() + class TestController { + @Get('error') + public error() { + throw error; + } + } + + const interceptor = new BacktraceExceptionHandler({ + skipIfClientUndefined: true, + }); + const handleException = jest.spyOn(interceptor, 'handleException'); + + const { app } = await createAppWithHandler(interceptor, TestController); + + await app.init(); + await request(app.getHttpServer()).get('/error').expect(500); + + const result = handleException.mock.results[0]; + expect(result.type).not.toEqual('throw'); + expect(result.value).toBe(false); + }); + describe('include', () => { it('should not send when error type is not on include list', async () => { const error = new BadRequestException('abc'); diff --git a/packages/nestjs/tests/backtrace.module.spec.ts b/packages/nestjs/tests/backtrace.module.spec.ts index 02fd32c4..94e2099b 100644 --- a/packages/nestjs/tests/backtrace.module.spec.ts +++ b/packages/nestjs/tests/backtrace.module.spec.ts @@ -56,4 +56,18 @@ describe('BacktraceModule', () => { }).compile(), ).rejects.toThrowError(/Backtrace instance is not available\./); }); + + it('should not throw an error when instance is not initialized and skipIfClientUndefined is true', async () => { + await expect( + Test.createTestingModule({ + imports: [ + BacktraceModule.register({ + options: { + skipIfClientUndefined: true, + }, + }), + ], + }).compile(), + ).resolves.not.toThrow(); + }); });