const OError = require('..') const { expectError } = require('./support') class CustomError1 extends OError { constructor(options) { super({ message: 'failed to foo', ...options }) } } class CustomError2 extends OError { constructor(options) { super({ message: 'failed to bar', ...options }) } } describe('OError', function () { it('handles a custom error type with a cause', function () { function doSomethingBadInternally() { throw new Error('internal error') } function doSomethingBad() { try { doSomethingBadInternally() } catch (err) { throw new CustomError1({ info: { userId: 123 } }).withCause(err) } } try { doSomethingBad() expect.fail('should have thrown') } catch (e) { expectError(e, { name: 'CustomError1', klass: CustomError1, message: 'CustomError1: failed to foo: internal error', firstFrameRx: /doSomethingBad/, }) expect(OError.getFullInfo(e)).to.deep.equal({ userId: 123 }) const fullStack = OError.getFullStack(e) expect(fullStack).to.match( /^CustomError1: failed to foo: internal error$/m ) expect(fullStack).to.match(/^caused by: Error: internal error$/m) } }) it('handles a custom error type with nested causes', function () { function doSomethingBadInternally() { throw new Error('internal error') } function doBar() { try { doSomethingBadInternally() } catch (err) { throw new CustomError2({ info: { database: 'a' } }).withCause(err) } } function doFoo() { try { doBar() } catch (err) { throw new CustomError1({ info: { userId: 123 } }).withCause(err) } } try { doFoo() expect.fail('should have thrown') } catch (e) { expectError(e, { name: 'CustomError1', klass: CustomError1, message: 'CustomError1: failed to foo: failed to bar: internal error', firstFrameRx: /doFoo/, }) expect(OError.getFullInfo(e)).to.deep.equal({ userId: 123, database: 'a', }) const fullStack = OError.getFullStack(e) expect(fullStack).to.match( /^CustomError1: failed to foo: failed to bar: internal error$/m ) expect(fullStack).to.match( /^caused by: CustomError2: failed to bar: internal error$/m ) expect(fullStack).to.match(/^caused by: Error: internal error$/m) } }) it('handles a custom error without info', function () { try { throw new CustomError1({}) } catch (e) { expect(OError.getFullInfo(e)).to.deep.equal({}) let infoKey = Object.keys(e).find((k) => k === 'info') expect(infoKey).to.not.exist } }) })