From efeffc184a663a6fe790bc84f2ec1afa50cf9156 Mon Sep 17 00:00:00 2001 From: Gonza Gluzman Date: Fri, 16 Mar 2018 18:05:45 -0300 Subject: [PATCH] feat(UncaughtError): preserve original stack --- src/task.ts | 3 +++ test/task.test.ts | 4 +-- test/uncaught-error.test.ts | 38 ++++++++++++++++++++++++++++ test/utils/as-uncaught-error.test.ts | 2 ++ 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 test/uncaught-error.test.ts diff --git a/src/task.ts b/src/task.ts index 6db800d..01a504f 100644 --- a/src/task.ts +++ b/src/task.ts @@ -6,6 +6,9 @@ export class UncaughtError extends Error { constructor (private error: any) { super('UncaughtError: ' + error.toString()); + + // Preserve original stack to ease debugging: + this.stack = error.stack; } } diff --git a/test/task.test.ts b/test/task.test.ts index e7f17b7..3105db6 100644 --- a/test/task.test.ts +++ b/test/task.test.ts @@ -1,8 +1,8 @@ +// Weird but I have to import "nothing" from "jest" to have the global jest functions (describe, etc.) available +import {} from 'jest'; import { Task, UncaughtError } from '../src/task'; import { assertFork, jestAssertNever, jestAssertUntypedNeverCalled } from './jest-helper'; - - describe('Task', () => { describe('fork', () => { it('should be lazy (dont call if not forked)', cb => { diff --git a/test/uncaught-error.test.ts b/test/uncaught-error.test.ts new file mode 100644 index 0000000..2d4291d --- /dev/null +++ b/test/uncaught-error.test.ts @@ -0,0 +1,38 @@ +// Weird but I have to import "nothing" from "jest" to have the global jest functions (describe, etc.) available +import {} from 'jest'; +import { UncaughtError } from '../src/task'; + +describe('UncaughtError', () => { + // Maintains wrapped error's stack + describe('.message', () => { + it('should include the wrapped error\'s message', () => { + const originalErrorMsg = 'Buuuu!'; + const wrappedError = new Error(originalErrorMsg); + expect(new UncaughtError(wrappedError).message).toMatch(originalErrorMsg); + }); + + it('should prepend "UncaughtError:"', () => { + const wrappedError = new Error('Buuuu!'); + expect(new UncaughtError(wrappedError).message).toMatch(/^UncaughtError\:/); + }); + }); + + describe('.stack', () => { + it('should mantain wrapped error\'s stack', () => { + // Throw an Error with an "interesting" stack + const foo = () => bar(); + const bar = () => baz(); + const baz = () => { + throw new Error('Buuuu!'); + }; + + try { + foo(); + } + catch (wrappedError) { + const uncaughtError = new UncaughtError(wrappedError); + expect(uncaughtError.stack).toBe(wrappedError.stack); + } + }); + }); +}); diff --git a/test/utils/as-uncaught-error.test.ts b/test/utils/as-uncaught-error.test.ts index 6efb2cf..6039e23 100644 --- a/test/utils/as-uncaught-error.test.ts +++ b/test/utils/as-uncaught-error.test.ts @@ -1,3 +1,5 @@ +// Weird but I have to import "nothing" from "jest" to have the global jest functions (describe, etc.) available +import {} from 'jest'; import { Task, UncaughtError } from '../../src/task'; import { asUncaughtError } from '../../src/utils/as-uncaught-error'; import { assertFork, jestAssertNever, jestAssertUntypedNeverCalled } from '../jest-helper';