From d66325e167c905de27a8d55413b5de9268ddb7a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Tue, 6 Dec 2022 18:01:06 +0100 Subject: [PATCH 1/5] Add more tests to the error handler --- packages/angular/test/errorhandler.test.ts | 118 +++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/packages/angular/test/errorhandler.test.ts b/packages/angular/test/errorhandler.test.ts index 324cbd0d1c7b..4935eea8ba13 100644 --- a/packages/angular/test/errorhandler.test.ts +++ b/packages/angular/test/errorhandler.test.ts @@ -79,6 +79,61 @@ describe('SentryErrorHandler', () => { expect(captureExceptionSpy).toHaveBeenCalledWith(err, expect.any(Function)); }); + it('handleError method extracts a non-empty Error', () => { + const err = new Error('sentry-test'); + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith(err, expect.any(Function)); + }); + + it('handleError method extracts an error-like object without stack', () => { + const errorLikeWithoutStack: Error = { + name: 'sentry-http-test', + message: 'something failed.', + }; + createErrorHandler().handleError(errorLikeWithoutStack); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + // TODO: to be changed; see https://github.com/getsentry/sentry-javascript/issues/6332 + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); + + it('handleError method extracts an error-like object with a stack', () => { + const errorLikeWithStack: Error = { + name: 'sentry-http-test', + message: 'something failed.', + stack: new Error().stack, + }; + createErrorHandler().handleError(errorLikeWithStack); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + // TODO: to be changed; see https://github.com/getsentry/sentry-javascript/issues/6332 + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); + + it('handleError method extracts an object that could look like an error but is not (does not have a message)', () => { + const notErr: Partial = { + name: 'sentry-http-test', + // missing message + }; + createErrorHandler().handleError(notErr); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); + + it('handleError method extracts an object that could look like an error but is not (does not have a name)', () => { + const notErr: Partial = { + // missing name + message: 'something failed.', + }; + createErrorHandler().handleError(notErr); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); + it('handleError method extracts an Error with `ngOriginalError`', () => { const ngErr = new Error('sentry-ng-test'); const err = { @@ -122,6 +177,69 @@ describe('SentryErrorHandler', () => { ); }); + it('handleError method extracts an `HttpErrorResponse` with error-like object without stack', () => { + const errorLikeWithoutStack: Error = { + name: 'sentry-http-test', + message: 'something failed.', + }; + const err = new HttpErrorResponse({ error: errorLikeWithoutStack }); + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + // TODO: to be changed; see https://github.com/getsentry/sentry-javascript/issues/6332 + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with error-like object with a stack', () => { + const errorLikeWithStack: Error = { + name: 'sentry-http-test', + message: 'something failed.', + stack: new Error().stack, + }; + const err = new HttpErrorResponse({ error: errorLikeWithStack }); + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + // TODO: to be changed; see https://github.com/getsentry/sentry-javascript/issues/6332 + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not (does not have a message)', () => { + const notErr: Partial = { + name: 'sentry-http-test', + // missing message + }; + const err = new HttpErrorResponse({ error: notErr }); + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not (does not have a name)', () => { + const notErr: Partial = { + // missing name + message: 'something failed.', + }; + const err = new HttpErrorResponse({ error: notErr }); + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + it('handleError method shows report dialog', () => { const showReportDialogSpy = jest.spyOn(SentryBrowser, 'showReportDialog'); From dade16579e6e23389821967b58c238de776b7c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Tue, 6 Dec 2022 19:07:31 +0100 Subject: [PATCH 2/5] Add more tests --- packages/angular/test/errorhandler.test.ts | 343 ++++++++++++++++++++- 1 file changed, 339 insertions(+), 4 deletions(-) diff --git a/packages/angular/test/errorhandler.test.ts b/packages/angular/test/errorhandler.test.ts index 4935eea8ba13..abfee67909a0 100644 --- a/packages/angular/test/errorhandler.test.ts +++ b/packages/angular/test/errorhandler.test.ts @@ -22,6 +22,22 @@ const captureExceptionSpy = jest.spyOn(SentryBrowser, 'captureException'); jest.spyOn(console, 'error').mockImplementation(); +class CustomError extends Error { + public name: string; + + constructor(public message: string) { + super(message); + + this.name = 'CustomError'; + } +} + +class ErrorLikeShapedClass implements Partial { + constructor(public message: string) {} +} + +class NonErrorShapedClass {} + describe('SentryErrorHandler', () => { beforeEach(() => { jest.clearAllMocks(); @@ -81,6 +97,7 @@ describe('SentryErrorHandler', () => { it('handleError method extracts a non-empty Error', () => { const err = new Error('sentry-test'); + createErrorHandler().handleError(err); expect(captureExceptionSpy).toHaveBeenCalledTimes(1); @@ -92,6 +109,7 @@ describe('SentryErrorHandler', () => { name: 'sentry-http-test', message: 'something failed.', }; + createErrorHandler().handleError(errorLikeWithoutStack); expect(captureExceptionSpy).toHaveBeenCalledTimes(1); @@ -105,6 +123,7 @@ describe('SentryErrorHandler', () => { message: 'something failed.', stack: new Error().stack, }; + createErrorHandler().handleError(errorLikeWithStack); expect(captureExceptionSpy).toHaveBeenCalledTimes(1); @@ -117,23 +136,131 @@ describe('SentryErrorHandler', () => { name: 'sentry-http-test', // missing message }; + createErrorHandler().handleError(notErr); expect(captureExceptionSpy).toHaveBeenCalledTimes(1); expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); }); - it('handleError method extracts an object that could look like an error but is not (does not have a name)', () => { + it('handleError method extracts an object that could look like an error but is not (does not have an explicit name)', () => { const notErr: Partial = { - // missing name + // missing name; but actually is always there as part of the Object prototype message: 'something failed.', }; + createErrorHandler().handleError(notErr); expect(captureExceptionSpy).toHaveBeenCalledTimes(1); expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); }); + it('handleError method extracts an object that could look like an error but is not: the name is of the wrong type', () => { + const notErr = { + name: true, // wrong type + message: 'something failed', + }; + + createErrorHandler().handleError(notErr); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); + + it('handleError method extracts an object that could look like an error but is not: the message is of the wrong type', () => { + const notErr = { + name: 'sentry-http-error', + message: true, // wrong type + }; + + createErrorHandler().handleError(notErr); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); + + it('handleError method extracts an instance of a class extending Error', () => { + const err = new CustomError('something happened'); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith(err, expect.any(Function)); + }); + + it('handleError method extracts an instance of class not extending Error but that has an error-like shape', () => { + const err = new ErrorLikeShapedClass('something happened'); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); + + it('handleError method extracts an instance of a class that does not extend Error and does not have an error-like shape', () => { + const notErr = new NonErrorShapedClass(); + + createErrorHandler().handleError(notErr); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); + + it('handleError method extracts ErrorEvent which has a string as an error', () => { + const innerErr = 'something happened'; + const err: ErrorEvent = { + ...({} as ErrorEvent), + error: innerErr, + }; + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); + + it('handleError method extracts ErrorEvent which has an error has an error', () => { + const innerErr = new Error('something happened'); + const err: ErrorEvent = { + ...({} as ErrorEvent), + error: innerErr, + }; + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); + + it('handleError method extracts ErrorEvent which has an error-like object has an error', () => { + const innerErr: Error = { + name: 'sentry-error', + message: 'something happened', + }; + const err: ErrorEvent = { + ...({} as ErrorEvent), + error: innerErr, + }; + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); + + it('handleError method extracts ErrorEvent which has an non-error-like object has an error', () => { + const innerErr = true; + const err: ErrorEvent = { + ...({} as ErrorEvent), + error: innerErr, + }; + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); + it('handleError method extracts an Error with `ngOriginalError`', () => { const ngErr = new Error('sentry-ng-test'); const err = { @@ -183,6 +310,7 @@ describe('SentryErrorHandler', () => { message: 'something failed.', }; const err = new HttpErrorResponse({ error: errorLikeWithoutStack }); + createErrorHandler().handleError(err); expect(captureExceptionSpy).toHaveBeenCalledTimes(1); @@ -200,6 +328,7 @@ describe('SentryErrorHandler', () => { stack: new Error().stack, }; const err = new HttpErrorResponse({ error: errorLikeWithStack }); + createErrorHandler().handleError(err); expect(captureExceptionSpy).toHaveBeenCalledTimes(1); @@ -216,6 +345,7 @@ describe('SentryErrorHandler', () => { // missing message }; const err = new HttpErrorResponse({ error: notErr }); + createErrorHandler().handleError(err); expect(captureExceptionSpy).toHaveBeenCalledTimes(1); @@ -225,12 +355,217 @@ describe('SentryErrorHandler', () => { ); }); - it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not (does not have a name)', () => { + it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not (does not have an explicit name)', () => { const notErr: Partial = { - // missing name + // missing name; but actually is always there as part of the Object prototype message: 'something failed.', }; const err = new HttpErrorResponse({ error: notErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not: the name is of the wrong type', () => { + const notErr = { + name: true, // wrong type + message: 'something failed', + }; + const err = new HttpErrorResponse({ error: notErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not: the message is of the wrong type', () => { + const notErr = { + name: 'sentry-http-error', + message: true, // wrong type + }; + const err = new HttpErrorResponse({ error: notErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not: the stack is of the wrong type', () => { + const notErr = { + name: 'sentry-http-error', + message: 'something failed', + stack: true, // wrong type + }; + const err = new HttpErrorResponse({ error: notErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an error-event which contains an error', () => { + const notErr = { + name: 'sentry-http-error', + message: 'something failed', + stack: true, // wrong type + }; + const err = new HttpErrorResponse({ error: notErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not: the name is of the wrong type', () => { + const notErr = { + name: true, // wrong type + message: 'something failed', + }; + const err = new HttpErrorResponse({ error: notErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not: the message is of the wrong type', () => { + const notErr = { + name: 'sentry-http-error', + message: true, // wrong type + }; + const err = new HttpErrorResponse({ error: notErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an instance of a class extending Error', () => { + const err = new CustomError('something happened'); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith(err, expect.any(Function)); + }); + + it('handleError method extracts an `HttpErrorResponse` with an instance of class not extending Error but that has an error-like shape', () => { + const innerErr = new ErrorLikeShapedClass('something happened'); + const err = new HttpErrorResponse({ error: innerErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an instance of a class that does not extend Error and does not have an error-like shape', () => { + const innerErr = new NonErrorShapedClass(); + const err = new HttpErrorResponse({ error: innerErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has a string as an error', () => { + const innerErrorEventErr = 'something happened'; + const innerErr: ErrorEvent = { + ...({} as ErrorEvent), + error: innerErrorEventErr, + }; + const err = new HttpErrorResponse({ error: innerErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has an error has an error', () => { + const innerErrorEventErr = new Error('something happened'); + const innerErr: ErrorEvent = { + ...({} as ErrorEvent), + error: innerErrorEventErr, + }; + const err = new HttpErrorResponse({ error: innerErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has an error-like object has an error', () => { + const innerErrorEventErr: Error = { + name: 'sentry-error', + message: 'something happened', + }; + const innerErr: ErrorEvent = { + ...({} as ErrorEvent), + error: innerErrorEventErr, + }; + const err = new HttpErrorResponse({ error: innerErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); + + it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has an non-error-like object has an error', () => { + const innerErrorEventErr = true; + const innerErr: ErrorEvent = { + ...({} as ErrorEvent), + error: innerErrorEventErr, + }; + const err = new HttpErrorResponse({ error: innerErr }); + createErrorHandler().handleError(err); expect(captureExceptionSpy).toHaveBeenCalledTimes(1); From f76021f9a452b9fe3bc1de68a9ecad7d239f99bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Tue, 6 Dec 2022 19:27:55 +0100 Subject: [PATCH 3/5] More tests --- packages/angular/test/errorhandler.test.ts | 72 +++++----------------- 1 file changed, 17 insertions(+), 55 deletions(-) diff --git a/packages/angular/test/errorhandler.test.ts b/packages/angular/test/errorhandler.test.ts index abfee67909a0..42395fdfe835 100644 --- a/packages/angular/test/errorhandler.test.ts +++ b/packages/angular/test/errorhandler.test.ts @@ -36,6 +36,10 @@ class ErrorLikeShapedClass implements Partial { constructor(public message: string) {} } +function createErrorEvent(message: string, innerError: any): ErrorEvent { + return new ErrorEvent('something', { message, error: innerError }); +} + class NonErrorShapedClass {} describe('SentryErrorHandler', () => { @@ -207,11 +211,7 @@ describe('SentryErrorHandler', () => { }); it('handleError method extracts ErrorEvent which has a string as an error', () => { - const innerErr = 'something happened'; - const err: ErrorEvent = { - ...({} as ErrorEvent), - error: innerErr, - }; + const err = createErrorEvent('something happened', 'event failed'); createErrorHandler().handleError(err); @@ -220,11 +220,7 @@ describe('SentryErrorHandler', () => { }); it('handleError method extracts ErrorEvent which has an error has an error', () => { - const innerErr = new Error('something happened'); - const err: ErrorEvent = { - ...({} as ErrorEvent), - error: innerErr, - }; + const err = createErrorEvent('something happened', new Error('event failed')); createErrorHandler().handleError(err); @@ -235,12 +231,9 @@ describe('SentryErrorHandler', () => { it('handleError method extracts ErrorEvent which has an error-like object has an error', () => { const innerErr: Error = { name: 'sentry-error', - message: 'something happened', - }; - const err: ErrorEvent = { - ...({} as ErrorEvent), - error: innerErr, + message: 'event failed', }; + const err = createErrorEvent('something happened', innerErr); createErrorHandler().handleError(err); @@ -249,11 +242,7 @@ describe('SentryErrorHandler', () => { }); it('handleError method extracts ErrorEvent which has an non-error-like object has an error', () => { - const innerErr = true; - const err: ErrorEvent = { - ...({} as ErrorEvent), - error: innerErr, - }; + const err = createErrorEvent('something happened', true); createErrorHandler().handleError(err); @@ -505,37 +494,23 @@ describe('SentryErrorHandler', () => { }); it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has a string as an error', () => { - const innerErrorEventErr = 'something happened'; - const innerErr: ErrorEvent = { - ...({} as ErrorEvent), - error: innerErrorEventErr, - }; + const innerErr = createErrorEvent('something happened', 'event failed'); const err = new HttpErrorResponse({ error: innerErr }); createErrorHandler().handleError(err); expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); + expect(captureExceptionSpy).toHaveBeenCalledWith('something happened', expect.any(Function)); }); it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has an error has an error', () => { - const innerErrorEventErr = new Error('something happened'); - const innerErr: ErrorEvent = { - ...({} as ErrorEvent), - error: innerErrorEventErr, - }; + const innerErr = createErrorEvent('something happened', new Error('event failed')); const err = new HttpErrorResponse({ error: innerErr }); createErrorHandler().handleError(err); expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); + expect(captureExceptionSpy).toHaveBeenCalledWith('something happened', expect.any(Function)); }); it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has an error-like object has an error', () => { @@ -543,36 +518,23 @@ describe('SentryErrorHandler', () => { name: 'sentry-error', message: 'something happened', }; - const innerErr: ErrorEvent = { - ...({} as ErrorEvent), - error: innerErrorEventErr, - }; + const innerErr = createErrorEvent('something happened', innerErrorEventErr); const err = new HttpErrorResponse({ error: innerErr }); createErrorHandler().handleError(err); expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); + expect(captureExceptionSpy).toHaveBeenCalledWith('something happened', expect.any(Function)); }); it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has an non-error-like object has an error', () => { - const innerErrorEventErr = true; - const innerErr: ErrorEvent = { - ...({} as ErrorEvent), - error: innerErrorEventErr, - }; + const innerErr = createErrorEvent('something happened', true); const err = new HttpErrorResponse({ error: innerErr }); createErrorHandler().handleError(err); expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); + expect(captureExceptionSpy).toHaveBeenCalledWith('something happened', expect.any(Function)); }); it('handleError method shows report dialog', () => { From a8db092e55308bbb1e40765ba4055f3ade2be783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= <5175937+theofidry@users.noreply.github.com> Date: Fri, 9 Dec 2022 09:48:50 +0100 Subject: [PATCH 4/5] Fix typo Co-authored-by: hunhejj --- packages/angular/test/errorhandler.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/angular/test/errorhandler.test.ts b/packages/angular/test/errorhandler.test.ts index 42395fdfe835..68fcabe5c28e 100644 --- a/packages/angular/test/errorhandler.test.ts +++ b/packages/angular/test/errorhandler.test.ts @@ -241,7 +241,7 @@ describe('SentryErrorHandler', () => { expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); }); - it('handleError method extracts ErrorEvent which has an non-error-like object has an error', () => { + it('handleError method extracts ErrorEvent which has a non-error-like object as an error', () => { const err = createErrorEvent('something happened', true); createErrorHandler().handleError(err); @@ -527,7 +527,7 @@ describe('SentryErrorHandler', () => { expect(captureExceptionSpy).toHaveBeenCalledWith('something happened', expect.any(Function)); }); - it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has an non-error-like object has an error', () => { + it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has a non-error-like object has an error', () => { const innerErr = createErrorEvent('something happened', true); const err = new HttpErrorResponse({ error: innerErr }); From e1b74c7496fd6dd89c213720c5735b4e36630e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Tue, 13 Dec 2022 21:58:39 +0100 Subject: [PATCH 5/5] Group tests under a describe --- packages/angular/test/errorhandler.test.ts | 778 ++++++++++----------- 1 file changed, 382 insertions(+), 396 deletions(-) diff --git a/packages/angular/test/errorhandler.test.ts b/packages/angular/test/errorhandler.test.ts index 68fcabe5c28e..df28e809bb26 100644 --- a/packages/angular/test/errorhandler.test.ts +++ b/packages/angular/test/errorhandler.test.ts @@ -53,511 +53,497 @@ describe('SentryErrorHandler', () => { expect(errorHandler).toBeInstanceOf(SentryErrorHandler); }); - it('handleError method assigns the correct mechanism', () => { - const addEventProcessorSpy = jest.spyOn(FakeScope, 'addEventProcessor').mockImplementationOnce(callback => { - void callback({}, { event_id: 'fake-event-id' }); - return FakeScope; - }); - - const addExceptionMechanismSpy = jest.spyOn(SentryUtils, 'addExceptionMechanism'); - - const errorHandler = createErrorHandler(); - errorHandler.handleError(new Error('test')); + describe('handleError method', () => { + it('handleError method assigns the correct mechanism', () => { + const addEventProcessorSpy = jest.spyOn(FakeScope, 'addEventProcessor').mockImplementationOnce(callback => { + void callback({}, { event_id: 'fake-event-id' }); + return FakeScope; + }); - expect(addEventProcessorSpy).toBeCalledTimes(1); - expect(addExceptionMechanismSpy).toBeCalledTimes(1); - expect(addExceptionMechanismSpy).toBeCalledWith({}, { handled: false, type: 'angular' }); - }); + const addExceptionMechanismSpy = jest.spyOn(SentryUtils, 'addExceptionMechanism'); - it('handleError method extracts `null` error', () => { - createErrorHandler().handleError(null); + const errorHandler = createErrorHandler(); + errorHandler.handleError(new Error('test')); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); - - it('handleError method extracts `undefined` error', () => { - createErrorHandler().handleError(undefined); + expect(addEventProcessorSpy).toBeCalledTimes(1); + expect(addExceptionMechanismSpy).toBeCalledTimes(1); + expect(addExceptionMechanismSpy).toBeCalledWith({}, { handled: false, type: 'angular' }); + }); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); + it('extracts `null` error', () => { + createErrorHandler().handleError(null); - it('handleError method extracts a string', () => { - const str = 'sentry-test'; - createErrorHandler().handleError(str); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith(str, expect.any(Function)); - }); + it('extracts `undefined` error', () => { + createErrorHandler().handleError(undefined); - it('handleError method extracts an empty Error', () => { - const err = new Error(); - createErrorHandler().handleError(err); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith(err, expect.any(Function)); - }); + it('extracts a string', () => { + const str = 'sentry-test'; + createErrorHandler().handleError(str); - it('handleError method extracts a non-empty Error', () => { - const err = new Error('sentry-test'); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith(str, expect.any(Function)); + }); - createErrorHandler().handleError(err); + it('extracts an empty Error', () => { + const err = new Error(); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith(err, expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith(err, expect.any(Function)); + }); - it('handleError method extracts an error-like object without stack', () => { - const errorLikeWithoutStack: Error = { - name: 'sentry-http-test', - message: 'something failed.', - }; + it('extracts a non-empty Error', () => { + const err = new Error('sentry-test'); - createErrorHandler().handleError(errorLikeWithoutStack); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - // TODO: to be changed; see https://github.com/getsentry/sentry-javascript/issues/6332 - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith(err, expect.any(Function)); + }); - it('handleError method extracts an error-like object with a stack', () => { - const errorLikeWithStack: Error = { - name: 'sentry-http-test', - message: 'something failed.', - stack: new Error().stack, - }; + it('extracts an error-like object without stack', () => { + const errorLikeWithoutStack: Error = { + name: 'sentry-http-test', + message: 'something failed.', + }; - createErrorHandler().handleError(errorLikeWithStack); + createErrorHandler().handleError(errorLikeWithoutStack); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - // TODO: to be changed; see https://github.com/getsentry/sentry-javascript/issues/6332 - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + // TODO: to be changed; see https://github.com/getsentry/sentry-javascript/issues/6332 + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - it('handleError method extracts an object that could look like an error but is not (does not have a message)', () => { - const notErr: Partial = { - name: 'sentry-http-test', - // missing message - }; + it('extracts an error-like object with a stack', () => { + const errorLikeWithStack: Error = { + name: 'sentry-http-test', + message: 'something failed.', + stack: new Error().stack, + }; - createErrorHandler().handleError(notErr); + createErrorHandler().handleError(errorLikeWithStack); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + // TODO: to be changed; see https://github.com/getsentry/sentry-javascript/issues/6332 + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - it('handleError method extracts an object that could look like an error but is not (does not have an explicit name)', () => { - const notErr: Partial = { - // missing name; but actually is always there as part of the Object prototype - message: 'something failed.', - }; + it('extracts an object that could look like an error but is not (does not have a message)', () => { + const notErr: Partial = { + name: 'sentry-http-test', + // missing message + }; - createErrorHandler().handleError(notErr); + createErrorHandler().handleError(notErr); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - it('handleError method extracts an object that could look like an error but is not: the name is of the wrong type', () => { - const notErr = { - name: true, // wrong type - message: 'something failed', - }; + it('extracts an object that could look like an error but is not (does not have an explicit name)', () => { + const notErr: Partial = { + // missing name; but actually is always there as part of the Object prototype + message: 'something failed.', + }; - createErrorHandler().handleError(notErr); + createErrorHandler().handleError(notErr); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - it('handleError method extracts an object that could look like an error but is not: the message is of the wrong type', () => { - const notErr = { - name: 'sentry-http-error', - message: true, // wrong type - }; + it('extracts an object that could look like an error but is not: the name is of the wrong type', () => { + const notErr = { + name: true, // wrong type + message: 'something failed', + }; - createErrorHandler().handleError(notErr); + createErrorHandler().handleError(notErr); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - it('handleError method extracts an instance of a class extending Error', () => { - const err = new CustomError('something happened'); + it('extracts an object that could look like an error but is not: the message is of the wrong type', () => { + const notErr = { + name: 'sentry-http-error', + message: true, // wrong type + }; - createErrorHandler().handleError(err); + createErrorHandler().handleError(notErr); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith(err, expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - it('handleError method extracts an instance of class not extending Error but that has an error-like shape', () => { - const err = new ErrorLikeShapedClass('something happened'); + it('extracts an instance of a class extending Error', () => { + const err = new CustomError('something happened'); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith(err, expect.any(Function)); + }); - it('handleError method extracts an instance of a class that does not extend Error and does not have an error-like shape', () => { - const notErr = new NonErrorShapedClass(); + it('extracts an instance of class not extending Error but that has an error-like shape', () => { + const err = new ErrorLikeShapedClass('something happened'); - createErrorHandler().handleError(notErr); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - it('handleError method extracts ErrorEvent which has a string as an error', () => { - const err = createErrorEvent('something happened', 'event failed'); + it('extracts an instance of a class that does not extend Error and does not have an error-like shape', () => { + const notErr = new NonErrorShapedClass(); - createErrorHandler().handleError(err); + createErrorHandler().handleError(notErr); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - it('handleError method extracts ErrorEvent which has an error has an error', () => { - const err = createErrorEvent('something happened', new Error('event failed')); + it('extracts ErrorEvent which has a string as an error', () => { + const err = createErrorEvent('something happened', 'event failed'); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - it('handleError method extracts ErrorEvent which has an error-like object has an error', () => { - const innerErr: Error = { - name: 'sentry-error', - message: 'event failed', - }; - const err = createErrorEvent('something happened', innerErr); + it('extracts ErrorEvent which has an error as an error', () => { + const err = createErrorEvent('something happened', new Error('event failed')); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - it('handleError method extracts ErrorEvent which has a non-error-like object as an error', () => { - const err = createErrorEvent('something happened', true); + it('extracts ErrorEvent which has an error-like object as an error', () => { + const innerErr: Error = { + name: 'sentry-error', + message: 'event failed', + }; + const err = createErrorEvent('something happened', innerErr); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - it('handleError method extracts an Error with `ngOriginalError`', () => { - const ngErr = new Error('sentry-ng-test'); - const err = { - ngOriginalError: ngErr, - }; + it('extracts ErrorEvent which has a non-error-like object as an error', () => { + const err = createErrorEvent('something happened', true); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith(ngErr, expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('Handled unknown error', expect.any(Function)); + }); - it('handleError method extracts an `HttpErrorResponse` with `Error`', () => { - const httpErr = new Error('sentry-http-test'); - const err = new HttpErrorResponse({ error: httpErr }); + it('extracts an Error with `ngOriginalError`', () => { + const ngErr = new Error('sentry-ng-test'); + const err = { + ngOriginalError: ngErr, + }; - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith(httpErr, expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith(ngErr, expect.any(Function)); + }); - it('handleError method extracts an `HttpErrorResponse` with `ErrorEvent`', () => { - const httpErr = new ErrorEvent('http', { message: 'sentry-http-test' }); - const err = new HttpErrorResponse({ error: httpErr }); + it('extracts an `HttpErrorResponse` with `Error`', () => { + const httpErr = new Error('sentry-http-test'); + const err = new HttpErrorResponse({ error: httpErr }); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('sentry-http-test', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith(httpErr, expect.any(Function)); + }); - it('handleError method extracts an `HttpErrorResponse` with string', () => { - const err = new HttpErrorResponse({ error: 'sentry-http-test' }); - createErrorHandler().handleError(err); + it('extracts an `HttpErrorResponse` with `ErrorEvent`', () => { + const httpErr = new ErrorEvent('http', { message: 'sentry-http-test' }); + const err = new HttpErrorResponse({ error: httpErr }); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Server returned code 0 with body "sentry-http-test"', - expect.any(Function), - ); - }); + createErrorHandler().handleError(err); - it('handleError method extracts an `HttpErrorResponse` with error-like object without stack', () => { - const errorLikeWithoutStack: Error = { - name: 'sentry-http-test', - message: 'something failed.', - }; - const err = new HttpErrorResponse({ error: errorLikeWithoutStack }); - - createErrorHandler().handleError(err); - - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - // TODO: to be changed; see https://github.com/getsentry/sentry-javascript/issues/6332 - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('sentry-http-test', expect.any(Function)); + }); - it('handleError method extracts an `HttpErrorResponse` with error-like object with a stack', () => { - const errorLikeWithStack: Error = { - name: 'sentry-http-test', - message: 'something failed.', - stack: new Error().stack, - }; - const err = new HttpErrorResponse({ error: errorLikeWithStack }); - - createErrorHandler().handleError(err); - - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - // TODO: to be changed; see https://github.com/getsentry/sentry-javascript/issues/6332 - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); - }); + it('extracts an `HttpErrorResponse` with string', () => { + const err = new HttpErrorResponse({ error: 'sentry-http-test' }); + createErrorHandler().handleError(err); - it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not (does not have a message)', () => { - const notErr: Partial = { - name: 'sentry-http-test', - // missing message - }; - const err = new HttpErrorResponse({ error: notErr }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Server returned code 0 with body "sentry-http-test"', + expect.any(Function), + ); + }); - createErrorHandler().handleError(err); + it('extracts an `HttpErrorResponse` with error-like object without stack', () => { + const errorLikeWithoutStack: Error = { + name: 'sentry-http-test', + message: 'something failed.', + }; + const err = new HttpErrorResponse({ error: errorLikeWithoutStack }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + // TODO: to be changed; see https://github.com/getsentry/sentry-javascript/issues/6332 + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); - }); + it('extracts an `HttpErrorResponse` with error-like object with a stack', () => { + const errorLikeWithStack: Error = { + name: 'sentry-http-test', + message: 'something failed.', + stack: new Error().stack, + }; + const err = new HttpErrorResponse({ error: errorLikeWithStack }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + // TODO: to be changed; see https://github.com/getsentry/sentry-javascript/issues/6332 + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); - it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not (does not have an explicit name)', () => { - const notErr: Partial = { - // missing name; but actually is always there as part of the Object prototype - message: 'something failed.', - }; - const err = new HttpErrorResponse({ error: notErr }); + it('extracts an `HttpErrorResponse` with an object that could look like an error but is not (does not have a message)', () => { + const notErr: Partial = { + name: 'sentry-http-test', + // missing message + }; + const err = new HttpErrorResponse({ error: notErr }); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); - it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not: the name is of the wrong type', () => { - const notErr = { - name: true, // wrong type - message: 'something failed', - }; - const err = new HttpErrorResponse({ error: notErr }); + it('extracts an `HttpErrorResponse` with an object that could look like an error but is not (does not have an explicit name)', () => { + const notErr: Partial = { + // missing name; but actually is always there as part of the Object prototype + message: 'something failed.', + }; + const err = new HttpErrorResponse({ error: notErr }); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); - it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not: the message is of the wrong type', () => { - const notErr = { - name: 'sentry-http-error', - message: true, // wrong type - }; - const err = new HttpErrorResponse({ error: notErr }); + it('extracts an `HttpErrorResponse` with an object that could look like an error but is not: the name is of the wrong type', () => { + const notErr = { + name: true, // wrong type + message: 'something failed', + }; + const err = new HttpErrorResponse({ error: notErr }); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); - it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not: the stack is of the wrong type', () => { - const notErr = { - name: 'sentry-http-error', - message: 'something failed', - stack: true, // wrong type - }; - const err = new HttpErrorResponse({ error: notErr }); - - createErrorHandler().handleError(err); - - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); - }); + it('extracts an `HttpErrorResponse` with an object that could look like an error but is not: the message is of the wrong type', () => { + const notErr = { + name: 'sentry-http-error', + message: true, // wrong type + }; + const err = new HttpErrorResponse({ error: notErr }); - it('handleError method extracts an `HttpErrorResponse` with an error-event which contains an error', () => { - const notErr = { - name: 'sentry-http-error', - message: 'something failed', - stack: true, // wrong type - }; - const err = new HttpErrorResponse({ error: notErr }); - - createErrorHandler().handleError(err); - - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); - }); + createErrorHandler().handleError(err); - it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not: the name is of the wrong type', () => { - const notErr = { - name: true, // wrong type - message: 'something failed', - }; - const err = new HttpErrorResponse({ error: notErr }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); - createErrorHandler().handleError(err); + it('extracts an `HttpErrorResponse` with an object that could look like an error but is not: the stack is of the wrong type', () => { + const notErr = { + name: 'sentry-http-error', + message: 'something failed', + stack: true, // wrong type + }; + const err = new HttpErrorResponse({ error: notErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); - }); + it('extracts an `HttpErrorResponse` with an error-event which contains an error', () => { + const notErr = { + name: 'sentry-http-error', + message: 'something failed', + stack: true, // wrong type + }; + const err = new HttpErrorResponse({ error: notErr }); + + createErrorHandler().handleError(err); + + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); - it('handleError method extracts an `HttpErrorResponse` with an object that could look like an error but is not: the message is of the wrong type', () => { - const notErr = { - name: 'sentry-http-error', - message: true, // wrong type - }; - const err = new HttpErrorResponse({ error: notErr }); + it('extracts an `HttpErrorResponse` with an object that could look like an error but is not: the message is of the wrong type', () => { + const notErr = { + name: 'sentry-http-error', + message: true, // wrong type + }; + const err = new HttpErrorResponse({ error: notErr }); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); - it('handleError method extracts an `HttpErrorResponse` with an instance of a class extending Error', () => { - const err = new CustomError('something happened'); + it('extracts an `HttpErrorResponse` with an instance of a class extending Error', () => { + const err = new CustomError('something happened'); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith(err, expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith(err, expect.any(Function)); + }); - it('handleError method extracts an `HttpErrorResponse` with an instance of class not extending Error but that has an error-like shape', () => { - const innerErr = new ErrorLikeShapedClass('something happened'); - const err = new HttpErrorResponse({ error: innerErr }); + it('extracts an `HttpErrorResponse` with an instance of class not extending Error but that has an error-like shape', () => { + const innerErr = new ErrorLikeShapedClass('something happened'); + const err = new HttpErrorResponse({ error: innerErr }); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); - it('handleError method extracts an `HttpErrorResponse` with an instance of a class that does not extend Error and does not have an error-like shape', () => { - const innerErr = new NonErrorShapedClass(); - const err = new HttpErrorResponse({ error: innerErr }); + it('extracts an `HttpErrorResponse` with an instance of a class that does not extend Error and does not have an error-like shape', () => { + const innerErr = new NonErrorShapedClass(); + const err = new HttpErrorResponse({ error: innerErr }); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith( - 'Http failure response for (unknown url): undefined undefined', - expect.any(Function), - ); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith( + 'Http failure response for (unknown url): undefined undefined', + expect.any(Function), + ); + }); - it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has a string as an error', () => { - const innerErr = createErrorEvent('something happened', 'event failed'); - const err = new HttpErrorResponse({ error: innerErr }); + it('extracts an `HttpErrorResponse` with an ErrorEvent which has a string as an error', () => { + const innerErr = createErrorEvent('something happened', 'event failed'); + const err = new HttpErrorResponse({ error: innerErr }); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('something happened', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('something happened', expect.any(Function)); + }); - it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has an error has an error', () => { - const innerErr = createErrorEvent('something happened', new Error('event failed')); - const err = new HttpErrorResponse({ error: innerErr }); + it('extracts an `HttpErrorResponse` with an ErrorEvent which has an error as an error', () => { + const innerErr = createErrorEvent('something happened', new Error('event failed')); + const err = new HttpErrorResponse({ error: innerErr }); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('something happened', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('something happened', expect.any(Function)); + }); - it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has an error-like object has an error', () => { - const innerErrorEventErr: Error = { - name: 'sentry-error', - message: 'something happened', - }; - const innerErr = createErrorEvent('something happened', innerErrorEventErr); - const err = new HttpErrorResponse({ error: innerErr }); + it('extracts an `HttpErrorResponse` with an ErrorEvent which has an error-like object as an error', () => { + const innerErrorEventErr: Error = { + name: 'sentry-error', + message: 'something happened', + }; + const innerErr = createErrorEvent('something happened', innerErrorEventErr); + const err = new HttpErrorResponse({ error: innerErr }); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('something happened', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('something happened', expect.any(Function)); + }); - it('handleError method extracts an `HttpErrorResponse` with an ErrorEvent which has a non-error-like object has an error', () => { - const innerErr = createErrorEvent('something happened', true); - const err = new HttpErrorResponse({ error: innerErr }); + it('extracts an `HttpErrorResponse` with an ErrorEvent which has a non-error-like object as an error', () => { + const innerErr = createErrorEvent('something happened', true); + const err = new HttpErrorResponse({ error: innerErr }); - createErrorHandler().handleError(err); + createErrorHandler().handleError(err); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith('something happened', expect.any(Function)); - }); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith('something happened', expect.any(Function)); + }); - it('handleError method shows report dialog', () => { - const showReportDialogSpy = jest.spyOn(SentryBrowser, 'showReportDialog'); + it('handleError method shows report dialog', () => { + const showReportDialogSpy = jest.spyOn(SentryBrowser, 'showReportDialog'); - const errorHandler = createErrorHandler({ showDialog: true }); - errorHandler.handleError(new Error('test')); + const errorHandler = createErrorHandler({ showDialog: true }); + errorHandler.handleError(new Error('test')); - expect(showReportDialogSpy).toBeCalledTimes(1); - }); + expect(showReportDialogSpy).toBeCalledTimes(1); + }); - it('handleError method extracts error with a custom extractor', () => { - const customExtractor = (error: unknown) => { - if (typeof error === 'string') { - return new Error(`custom ${error}`); - } - return error; - }; + it('extracts error with a custom extractor', () => { + const customExtractor = (error: unknown) => { + if (typeof error === 'string') { + return new Error(`custom ${error}`); + } + return error; + }; - const errorHandler = createErrorHandler({ extractor: customExtractor }); - errorHandler.handleError('error'); + const errorHandler = createErrorHandler({ extractor: customExtractor }); + errorHandler.handleError('error'); - expect(captureExceptionSpy).toHaveBeenCalledTimes(1); - expect(captureExceptionSpy).toHaveBeenCalledWith(new Error('custom error'), expect.any(Function)); + expect(captureExceptionSpy).toHaveBeenCalledTimes(1); + expect(captureExceptionSpy).toHaveBeenCalledWith(new Error('custom error'), expect.any(Function)); + }); }); });