|
@@ -8,400 +8,406 @@ const {
|
|
|
expectFullStackWithoutStackFramesToEqual,
|
|
expectFullStackWithoutStackFramesToEqual,
|
|
|
} = require('./support')
|
|
} = require('./support')
|
|
|
|
|
|
|
|
-describe('OError.tag', function () {
|
|
|
|
|
- it('tags errors thrown from an async function', async function () {
|
|
|
|
|
- const delay = promisify(setTimeout)
|
|
|
|
|
-
|
|
|
|
|
- async function foo() {
|
|
|
|
|
- await delay(10)
|
|
|
|
|
- throw new Error('foo error')
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- async function bar() {
|
|
|
|
|
- try {
|
|
|
|
|
- await foo()
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- throw OError.tag(error, 'failed to bar', { bar: 'baz' })
|
|
|
|
|
|
|
+describe('utils', function () {
|
|
|
|
|
+ describe('OError.tag', function () {
|
|
|
|
|
+ it('tags errors thrown from an async function', async function () {
|
|
|
|
|
+ const delay = promisify(setTimeout)
|
|
|
|
|
+
|
|
|
|
|
+ async function foo() {
|
|
|
|
|
+ await delay(10)
|
|
|
|
|
+ throw new Error('foo error')
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- async function baz() {
|
|
|
|
|
- try {
|
|
|
|
|
- await bar()
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- throw OError.tag(error, 'failed to baz', { baz: 'bat' })
|
|
|
|
|
|
|
+ async function bar() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await foo()
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ throw OError.tag(error, 'failed to bar', { bar: 'baz' })
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- await baz()
|
|
|
|
|
- expect.fail('should have thrown')
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- expectError(error, {
|
|
|
|
|
- name: 'Error',
|
|
|
|
|
- klass: Error,
|
|
|
|
|
- message: 'Error: foo error',
|
|
|
|
|
- firstFrameRx: /at foo/,
|
|
|
|
|
- })
|
|
|
|
|
- expectFullStackWithoutStackFramesToEqual(error, [
|
|
|
|
|
- 'Error: foo error',
|
|
|
|
|
- 'TaggedError: failed to bar',
|
|
|
|
|
- 'TaggedError: failed to baz',
|
|
|
|
|
- ])
|
|
|
|
|
- expect(OError.getFullInfo(error)).to.eql({
|
|
|
|
|
- bar: 'baz',
|
|
|
|
|
- baz: 'bat',
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('tags errors thrown from a promise rejection', async function () {
|
|
|
|
|
- function foo() {
|
|
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
|
|
- setTimeout(function () {
|
|
|
|
|
- reject(new Error('foo error'))
|
|
|
|
|
- }, 10)
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- async function bar() {
|
|
|
|
|
- try {
|
|
|
|
|
- await foo()
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- throw OError.tag(error, 'failed to bar', { bar: 'baz' })
|
|
|
|
|
|
|
+ async function baz() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await bar()
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ throw OError.tag(error, 'failed to baz', { baz: 'bat' })
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- async function baz() {
|
|
|
|
|
try {
|
|
try {
|
|
|
- await bar()
|
|
|
|
|
|
|
+ await baz()
|
|
|
|
|
+ expect.fail('should have thrown')
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
- throw OError.tag(error, 'failed to baz', { baz: 'bat' })
|
|
|
|
|
|
|
+ expectError(error, {
|
|
|
|
|
+ name: 'Error',
|
|
|
|
|
+ klass: Error,
|
|
|
|
|
+ message: 'Error: foo error',
|
|
|
|
|
+ firstFrameRx: /at foo/,
|
|
|
|
|
+ })
|
|
|
|
|
+ expectFullStackWithoutStackFramesToEqual(error, [
|
|
|
|
|
+ 'Error: foo error',
|
|
|
|
|
+ 'TaggedError: failed to bar',
|
|
|
|
|
+ 'TaggedError: failed to baz',
|
|
|
|
|
+ ])
|
|
|
|
|
+ expect(OError.getFullInfo(error)).to.eql({
|
|
|
|
|
+ bar: 'baz',
|
|
|
|
|
+ baz: 'bat',
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- await baz()
|
|
|
|
|
- expect.fail('should have thrown')
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- expectError(error, {
|
|
|
|
|
- name: 'Error',
|
|
|
|
|
- klass: Error,
|
|
|
|
|
- message: 'Error: foo error',
|
|
|
|
|
- firstFrameRx: /_onTimeout/,
|
|
|
|
|
- })
|
|
|
|
|
- expectFullStackWithoutStackFramesToEqual(error, [
|
|
|
|
|
- 'Error: foo error',
|
|
|
|
|
- 'TaggedError: failed to bar',
|
|
|
|
|
- 'TaggedError: failed to baz',
|
|
|
|
|
- ])
|
|
|
|
|
- expect(OError.getFullInfo(error)).to.eql({
|
|
|
|
|
- bar: 'baz',
|
|
|
|
|
- baz: 'bat',
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- it('tags errors yielded through callbacks', function (done) {
|
|
|
|
|
- function foo(cb) {
|
|
|
|
|
- setTimeout(function () {
|
|
|
|
|
- cb(new Error('foo error'))
|
|
|
|
|
- }, 10)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ it('tags errors thrown from a promise rejection', async function () {
|
|
|
|
|
+ function foo() {
|
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ reject(new Error('foo error'))
|
|
|
|
|
+ }, 10)
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- function bar(cb) {
|
|
|
|
|
- foo(function (err) {
|
|
|
|
|
- if (err) {
|
|
|
|
|
- return cb(OError.tag(err, 'failed to bar', { bar: 'baz' }))
|
|
|
|
|
|
|
+ async function bar() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await foo()
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ throw OError.tag(error, 'failed to bar', { bar: 'baz' })
|
|
|
}
|
|
}
|
|
|
- cb()
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- function baz(cb) {
|
|
|
|
|
- bar(function (err) {
|
|
|
|
|
- if (err) {
|
|
|
|
|
- return cb(OError.tag(err, 'failed to baz', { baz: 'bat' }))
|
|
|
|
|
|
|
+ async function baz() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await bar()
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ throw OError.tag(error, 'failed to baz', { baz: 'bat' })
|
|
|
}
|
|
}
|
|
|
- cb()
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- baz(function (err) {
|
|
|
|
|
- if (err) {
|
|
|
|
|
- expectError(err, {
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ await baz()
|
|
|
|
|
+ expect.fail('should have thrown')
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ expectError(error, {
|
|
|
name: 'Error',
|
|
name: 'Error',
|
|
|
klass: Error,
|
|
klass: Error,
|
|
|
message: 'Error: foo error',
|
|
message: 'Error: foo error',
|
|
|
firstFrameRx: /_onTimeout/,
|
|
firstFrameRx: /_onTimeout/,
|
|
|
})
|
|
})
|
|
|
- expectFullStackWithoutStackFramesToEqual(err, [
|
|
|
|
|
|
|
+ expectFullStackWithoutStackFramesToEqual(error, [
|
|
|
'Error: foo error',
|
|
'Error: foo error',
|
|
|
'TaggedError: failed to bar',
|
|
'TaggedError: failed to bar',
|
|
|
'TaggedError: failed to baz',
|
|
'TaggedError: failed to baz',
|
|
|
])
|
|
])
|
|
|
- expect(OError.getFullInfo(err)).to.eql({
|
|
|
|
|
|
|
+ expect(OError.getFullInfo(error)).to.eql({
|
|
|
bar: 'baz',
|
|
bar: 'baz',
|
|
|
baz: 'bat',
|
|
baz: 'bat',
|
|
|
})
|
|
})
|
|
|
- return done()
|
|
|
|
|
}
|
|
}
|
|
|
- expect.fail('should have yielded an error')
|
|
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- it('is not included in the stack trace if using capture', function () {
|
|
|
|
|
- if (!Error.captureStackTrace) return this.skip()
|
|
|
|
|
- const err = new Error('test error')
|
|
|
|
|
- OError.tag(err, 'test message')
|
|
|
|
|
- const stack = OError.getFullStack(err)
|
|
|
|
|
- expect(stack).to.match(/TaggedError: test message\n\s+at/)
|
|
|
|
|
- expect(stack).to.not.match(/TaggedError: test message\n\s+at [\w.]*tag/)
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ it('tags errors yielded through callbacks', function (done) {
|
|
|
|
|
+ function foo(cb) {
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ cb(new Error('foo error'))
|
|
|
|
|
+ }, 10)
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- describe('without Error.captureStackTrace', function () {
|
|
|
|
|
- /* eslint-disable mocha/no-hooks-for-single-case */
|
|
|
|
|
- before(function () {
|
|
|
|
|
- this.originalCaptureStackTrace = Error.captureStackTrace
|
|
|
|
|
- Error.captureStackTrace = null
|
|
|
|
|
- })
|
|
|
|
|
- after(function () {
|
|
|
|
|
- Error.captureStackTrace = this.originalCaptureStackTrace
|
|
|
|
|
|
|
+ function bar(cb) {
|
|
|
|
|
+ foo(err => {
|
|
|
|
|
+ if (err) {
|
|
|
|
|
+ return cb(OError.tag(err, 'failed to bar', { bar: 'baz' }))
|
|
|
|
|
+ }
|
|
|
|
|
+ cb()
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function baz(cb) {
|
|
|
|
|
+ bar(err => {
|
|
|
|
|
+ if (err) {
|
|
|
|
|
+ return cb(OError.tag(err, 'failed to baz', { baz: 'bat' }))
|
|
|
|
|
+ }
|
|
|
|
|
+ cb()
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ baz(err => {
|
|
|
|
|
+ if (err) {
|
|
|
|
|
+ expectError(err, {
|
|
|
|
|
+ name: 'Error',
|
|
|
|
|
+ klass: Error,
|
|
|
|
|
+ message: 'Error: foo error',
|
|
|
|
|
+ firstFrameRx: /_onTimeout/,
|
|
|
|
|
+ })
|
|
|
|
|
+ expectFullStackWithoutStackFramesToEqual(err, [
|
|
|
|
|
+ 'Error: foo error',
|
|
|
|
|
+ 'TaggedError: failed to bar',
|
|
|
|
|
+ 'TaggedError: failed to baz',
|
|
|
|
|
+ ])
|
|
|
|
|
+ expect(OError.getFullInfo(err)).to.eql({
|
|
|
|
|
+ bar: 'baz',
|
|
|
|
|
+ baz: 'bat',
|
|
|
|
|
+ })
|
|
|
|
|
+ return done()
|
|
|
|
|
+ }
|
|
|
|
|
+ expect.fail('should have yielded an error')
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- it('still captures a stack trace, albeit including itself', function () {
|
|
|
|
|
|
|
+ it('is not included in the stack trace if using capture', function () {
|
|
|
|
|
+ if (!Error.captureStackTrace) return this.skip()
|
|
|
const err = new Error('test error')
|
|
const err = new Error('test error')
|
|
|
OError.tag(err, 'test message')
|
|
OError.tag(err, 'test message')
|
|
|
- expectFullStackWithoutStackFramesToEqual(err, [
|
|
|
|
|
- 'Error: test error',
|
|
|
|
|
- 'TaggedError: test message',
|
|
|
|
|
- ])
|
|
|
|
|
const stack = OError.getFullStack(err)
|
|
const stack = OError.getFullStack(err)
|
|
|
- expect(stack).to.match(/TaggedError: test message\n\s+at [\w.]*tag/)
|
|
|
|
|
|
|
+ expect(stack).to.match(/TaggedError: test message\n\s+at/)
|
|
|
|
|
+ expect(stack).to.not.match(/TaggedError: test message\n\s+at [\w.]*tag/)
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- describe('with limit on the number of tags', function () {
|
|
|
|
|
- before(function () {
|
|
|
|
|
- this.originalMaxTags = OError.maxTags
|
|
|
|
|
- OError.maxTags = 3
|
|
|
|
|
- })
|
|
|
|
|
- after(function () {
|
|
|
|
|
- OError.maxTags = this.originalMaxTags
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ describe('without Error.captureStackTrace', function () {
|
|
|
|
|
+ /* eslint-disable mocha/no-hooks-for-single-case */
|
|
|
|
|
+ before(function () {
|
|
|
|
|
+ this.originalCaptureStackTrace = Error.captureStackTrace
|
|
|
|
|
+ Error.captureStackTrace = null
|
|
|
|
|
+ })
|
|
|
|
|
+ after(function () {
|
|
|
|
|
+ Error.captureStackTrace = this.originalCaptureStackTrace
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- it('should not tag more than that', function () {
|
|
|
|
|
- const err = new Error('test error')
|
|
|
|
|
- OError.tag(err, 'test message 1')
|
|
|
|
|
- OError.tag(err, 'test message 2')
|
|
|
|
|
- OError.tag(err, 'test message 3')
|
|
|
|
|
- OError.tag(err, 'test message 4')
|
|
|
|
|
- OError.tag(err, 'test message 5')
|
|
|
|
|
- expectFullStackWithoutStackFramesToEqual(err, [
|
|
|
|
|
- 'Error: test error',
|
|
|
|
|
- 'TaggedError: test message 1',
|
|
|
|
|
- 'TaggedError: ... dropped tags',
|
|
|
|
|
- 'TaggedError: test message 4',
|
|
|
|
|
- 'TaggedError: test message 5',
|
|
|
|
|
- ])
|
|
|
|
|
|
|
+ it('still captures a stack trace, albeit including itself', function () {
|
|
|
|
|
+ const err = new Error('test error')
|
|
|
|
|
+ OError.tag(err, 'test message')
|
|
|
|
|
+ expectFullStackWithoutStackFramesToEqual(err, [
|
|
|
|
|
+ 'Error: test error',
|
|
|
|
|
+ 'TaggedError: test message',
|
|
|
|
|
+ ])
|
|
|
|
|
+ const stack = OError.getFullStack(err)
|
|
|
|
|
+ expect(stack).to.match(/TaggedError: test message\n\s+at [\w.]*tag/)
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- it('should handle deep recursion', async function () {
|
|
|
|
|
- async function recursiveAdd(n) {
|
|
|
|
|
- try {
|
|
|
|
|
- if (n === 0) throw new Error('deep error')
|
|
|
|
|
- const result = await recursiveAdd(n - 1)
|
|
|
|
|
- return result + 1
|
|
|
|
|
- } catch (err) {
|
|
|
|
|
- throw OError.tag(err, `at level ${n}`)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- try {
|
|
|
|
|
- await recursiveAdd(10)
|
|
|
|
|
- } catch (err) {
|
|
|
|
|
|
|
+ describe('with limit on the number of tags', function () {
|
|
|
|
|
+ before(function () {
|
|
|
|
|
+ this.originalMaxTags = OError.maxTags
|
|
|
|
|
+ OError.maxTags = 3
|
|
|
|
|
+ })
|
|
|
|
|
+ after(function () {
|
|
|
|
|
+ OError.maxTags = this.originalMaxTags
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ it('should not tag more than that', function () {
|
|
|
|
|
+ const err = new Error('test error')
|
|
|
|
|
+ OError.tag(err, 'test message 1')
|
|
|
|
|
+ OError.tag(err, 'test message 2')
|
|
|
|
|
+ OError.tag(err, 'test message 3')
|
|
|
|
|
+ OError.tag(err, 'test message 4')
|
|
|
|
|
+ OError.tag(err, 'test message 5')
|
|
|
expectFullStackWithoutStackFramesToEqual(err, [
|
|
expectFullStackWithoutStackFramesToEqual(err, [
|
|
|
- 'Error: deep error',
|
|
|
|
|
- 'TaggedError: at level 0',
|
|
|
|
|
|
|
+ 'Error: test error',
|
|
|
|
|
+ 'TaggedError: test message 1',
|
|
|
'TaggedError: ... dropped tags',
|
|
'TaggedError: ... dropped tags',
|
|
|
- 'TaggedError: at level 9',
|
|
|
|
|
- 'TaggedError: at level 10',
|
|
|
|
|
|
|
+ 'TaggedError: test message 4',
|
|
|
|
|
+ 'TaggedError: test message 5',
|
|
|
])
|
|
])
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- it('should handle a singleton error', function (done) {
|
|
|
|
|
- const err = new Error('singleton error')
|
|
|
|
|
- function endpoint(callback) {
|
|
|
|
|
- helper((err) => callback(err && OError.tag(err, 'in endpoint')))
|
|
|
|
|
- }
|
|
|
|
|
- function helper(callback) {
|
|
|
|
|
- libraryFunction((err) => callback(err && OError.tag(err, 'in helper')))
|
|
|
|
|
- }
|
|
|
|
|
- function libraryFunction(callback) {
|
|
|
|
|
- callback(err)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ it('should handle deep recursion', async function () {
|
|
|
|
|
+ async function recursiveAdd(n) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (n === 0) throw new Error('deep error')
|
|
|
|
|
+ const result = await recursiveAdd(n - 1)
|
|
|
|
|
+ return result + 1
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ throw OError.tag(err, `at level ${n}`)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- endpoint(() => {
|
|
|
|
|
- endpoint((err) => {
|
|
|
|
|
- expect(err).to.exist
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ await recursiveAdd(10)
|
|
|
|
|
+ } catch (err) {
|
|
|
expectFullStackWithoutStackFramesToEqual(err, [
|
|
expectFullStackWithoutStackFramesToEqual(err, [
|
|
|
- 'Error: singleton error',
|
|
|
|
|
- 'TaggedError: in helper',
|
|
|
|
|
|
|
+ 'Error: deep error',
|
|
|
|
|
+ 'TaggedError: at level 0',
|
|
|
'TaggedError: ... dropped tags',
|
|
'TaggedError: ... dropped tags',
|
|
|
- 'TaggedError: in helper',
|
|
|
|
|
- 'TaggedError: in endpoint',
|
|
|
|
|
|
|
+ 'TaggedError: at level 9',
|
|
|
|
|
+ 'TaggedError: at level 10',
|
|
|
])
|
|
])
|
|
|
- done()
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ it('should handle a singleton error', function (done) {
|
|
|
|
|
+ const err = new Error('singleton error')
|
|
|
|
|
+
|
|
|
|
|
+ function endpoint(callback) {
|
|
|
|
|
+ helper(err => callback(err && OError.tag(err, 'in endpoint')))
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function helper(callback) {
|
|
|
|
|
+ libraryFunction(err => callback(err && OError.tag(err, 'in helper')))
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function libraryFunction(callback) {
|
|
|
|
|
+ callback(err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ endpoint(() => {
|
|
|
|
|
+ endpoint(err => {
|
|
|
|
|
+ expect(err).to.exist
|
|
|
|
|
+ expectFullStackWithoutStackFramesToEqual(err, [
|
|
|
|
|
+ 'Error: singleton error',
|
|
|
|
|
+ 'TaggedError: in helper',
|
|
|
|
|
+ 'TaggedError: ... dropped tags',
|
|
|
|
|
+ 'TaggedError: in helper',
|
|
|
|
|
+ 'TaggedError: in endpoint',
|
|
|
|
|
+ ])
|
|
|
|
|
+ done()
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
-})
|
|
|
|
|
|
|
|
|
|
-describe('OError.getFullInfo', function () {
|
|
|
|
|
- it('works when given null', function () {
|
|
|
|
|
- expect(OError.getFullInfo(null)).to.deep.equal({})
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ describe('OError.getFullInfo', function () {
|
|
|
|
|
+ it('works when given null', function () {
|
|
|
|
|
+ expect(OError.getFullInfo(null)).to.deep.equal({})
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- it('works on a normal error', function () {
|
|
|
|
|
- const err = new Error('foo')
|
|
|
|
|
- expect(OError.getFullInfo(err)).to.deep.equal({})
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ it('works on a normal error', function () {
|
|
|
|
|
+ const err = new Error('foo')
|
|
|
|
|
+ expect(OError.getFullInfo(err)).to.deep.equal({})
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- it('works on an error with tags', function () {
|
|
|
|
|
- const err = OError.tag(new Error('foo'), 'bar', { userId: 123 })
|
|
|
|
|
- expect(OError.getFullInfo(err)).to.deep.equal({ userId: 123 })
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ it('works on an error with tags', function () {
|
|
|
|
|
+ const err = OError.tag(new Error('foo'), 'bar', { userId: 123 })
|
|
|
|
|
+ expect(OError.getFullInfo(err)).to.deep.equal({ userId: 123 })
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- it('merges info from an error and its tags', function () {
|
|
|
|
|
- const err = new OError('foo').withInfo({ projectId: 456 })
|
|
|
|
|
- OError.tag(err, 'failed to foo', { userId: 123 })
|
|
|
|
|
- expect(OError.getFullInfo(err)).to.deep.equal({
|
|
|
|
|
- projectId: 456,
|
|
|
|
|
- userId: 123,
|
|
|
|
|
|
|
+ it('merges info from an error and its tags', function () {
|
|
|
|
|
+ const err = new OError('foo').withInfo({ projectId: 456 })
|
|
|
|
|
+ OError.tag(err, 'failed to foo', { userId: 123 })
|
|
|
|
|
+ expect(OError.getFullInfo(err)).to.deep.equal({
|
|
|
|
|
+ projectId: 456,
|
|
|
|
|
+ userId: 123,
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- it('merges info from a cause', function () {
|
|
|
|
|
- const err1 = new Error('foo')
|
|
|
|
|
- const err2 = new Error('bar')
|
|
|
|
|
- err1.cause = err2
|
|
|
|
|
- err2.info = { userId: 123 }
|
|
|
|
|
- expect(OError.getFullInfo(err1)).to.deep.equal({ userId: 123 })
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ it('merges info from a cause', function () {
|
|
|
|
|
+ const err1 = new Error('foo')
|
|
|
|
|
+ const err2 = new Error('bar')
|
|
|
|
|
+ err1.cause = err2
|
|
|
|
|
+ err2.info = { userId: 123 }
|
|
|
|
|
+ expect(OError.getFullInfo(err1)).to.deep.equal({ userId: 123 })
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- it('merges info from a nested cause', function () {
|
|
|
|
|
- const err1 = new Error('foo')
|
|
|
|
|
- const err2 = new Error('bar')
|
|
|
|
|
- const err3 = new Error('baz')
|
|
|
|
|
- err1.cause = err2
|
|
|
|
|
- err2.info = { userId: 123 }
|
|
|
|
|
- err2.cause = err3
|
|
|
|
|
- err3.info = { foo: 42 }
|
|
|
|
|
- expect(OError.getFullInfo(err1)).to.deep.equal({
|
|
|
|
|
- userId: 123,
|
|
|
|
|
- foo: 42,
|
|
|
|
|
|
|
+ it('merges info from a nested cause', function () {
|
|
|
|
|
+ const err1 = new Error('foo')
|
|
|
|
|
+ const err2 = new Error('bar')
|
|
|
|
|
+ const err3 = new Error('baz')
|
|
|
|
|
+ err1.cause = err2
|
|
|
|
|
+ err2.info = { userId: 123 }
|
|
|
|
|
+ err2.cause = err3
|
|
|
|
|
+ err3.info = { foo: 42 }
|
|
|
|
|
+ expect(OError.getFullInfo(err1)).to.deep.equal({
|
|
|
|
|
+ userId: 123,
|
|
|
|
|
+ foo: 42,
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- it('merges info from cause with duplicate keys', function () {
|
|
|
|
|
- const err1 = new Error('foo')
|
|
|
|
|
- const err2 = new Error('bar')
|
|
|
|
|
- err1.info = { userId: 42, foo: 1337 }
|
|
|
|
|
- err1.cause = err2
|
|
|
|
|
- err2.info = { userId: 1 }
|
|
|
|
|
- expect(OError.getFullInfo(err1)).to.deep.equal({
|
|
|
|
|
- userId: 42,
|
|
|
|
|
- foo: 1337,
|
|
|
|
|
|
|
+ it('merges info from cause with duplicate keys', function () {
|
|
|
|
|
+ const err1 = new Error('foo')
|
|
|
|
|
+ const err2 = new Error('bar')
|
|
|
|
|
+ err1.info = { userId: 42, foo: 1337 }
|
|
|
|
|
+ err1.cause = err2
|
|
|
|
|
+ err2.info = { userId: 1 }
|
|
|
|
|
+ expect(OError.getFullInfo(err1)).to.deep.equal({
|
|
|
|
|
+ userId: 42,
|
|
|
|
|
+ foo: 1337,
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- it('merges info from tags with duplicate keys', function () {
|
|
|
|
|
- const err1 = OError.tag(new Error('foo'), 'bar', { userId: 123 })
|
|
|
|
|
- const err2 = OError.tag(err1, 'bat', { userId: 456 })
|
|
|
|
|
- expect(OError.getFullInfo(err2)).to.deep.equal({ userId: 456 })
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ it('merges info from tags with duplicate keys', function () {
|
|
|
|
|
+ const err1 = OError.tag(new Error('foo'), 'bar', { userId: 123 })
|
|
|
|
|
+ const err2 = OError.tag(err1, 'bat', { userId: 456 })
|
|
|
|
|
+ expect(OError.getFullInfo(err2)).to.deep.equal({ userId: 456 })
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- it('works on an error with .info set to a string', function () {
|
|
|
|
|
- const err = new Error('foo')
|
|
|
|
|
- err.info = 'test'
|
|
|
|
|
- expect(OError.getFullInfo(err)).to.deep.equal({})
|
|
|
|
|
|
|
+ it('works on an error with .info set to a string', function () {
|
|
|
|
|
+ const err = new Error('foo')
|
|
|
|
|
+ err.info = 'test'
|
|
|
|
|
+ expect(OError.getFullInfo(err)).to.deep.equal({})
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
-})
|
|
|
|
|
|
|
|
|
|
-describe('OError.getFullStack', function () {
|
|
|
|
|
- it('works when given null', function () {
|
|
|
|
|
- expect(OError.getFullStack(null)).to.equal('')
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ describe('OError.getFullStack', function () {
|
|
|
|
|
+ it('works when given null', function () {
|
|
|
|
|
+ expect(OError.getFullStack(null)).to.equal('')
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- it('works on a normal error', function () {
|
|
|
|
|
- const err = new Error('foo')
|
|
|
|
|
- const fullStack = OError.getFullStack(err)
|
|
|
|
|
- expect(fullStack).to.match(/^Error: foo$/m)
|
|
|
|
|
- expect(fullStack).to.match(/^\s+at /m)
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ it('works on a normal error', function () {
|
|
|
|
|
+ const err = new Error('foo')
|
|
|
|
|
+ const fullStack = OError.getFullStack(err)
|
|
|
|
|
+ expect(fullStack).to.match(/^Error: foo$/m)
|
|
|
|
|
+ expect(fullStack).to.match(/^\s+at /m)
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- it('works on an error with a cause', function () {
|
|
|
|
|
- const err1 = new Error('foo')
|
|
|
|
|
- const err2 = new Error('bar')
|
|
|
|
|
- err1.cause = err2
|
|
|
|
|
|
|
+ it('works on an error with a cause', function () {
|
|
|
|
|
+ const err1 = new Error('foo')
|
|
|
|
|
+ const err2 = new Error('bar')
|
|
|
|
|
+ err1.cause = err2
|
|
|
|
|
|
|
|
- const fullStack = OError.getFullStack(err1)
|
|
|
|
|
- expect(fullStack).to.match(/^Error: foo$/m)
|
|
|
|
|
- expect(fullStack).to.match(/^\s+at /m)
|
|
|
|
|
- expect(fullStack).to.match(/^caused by:\n\s+Error: bar$/m)
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ const fullStack = OError.getFullStack(err1)
|
|
|
|
|
+ expect(fullStack).to.match(/^Error: foo$/m)
|
|
|
|
|
+ expect(fullStack).to.match(/^\s+at /m)
|
|
|
|
|
+ expect(fullStack).to.match(/^caused by:\n\s+Error: bar$/m)
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- it('works on both tags and causes', async function () {
|
|
|
|
|
- // Here's the actual error.
|
|
|
|
|
- function tryToFoo() {
|
|
|
|
|
- try {
|
|
|
|
|
- throw Error('foo')
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- throw OError.tag(error, 'failed to foo', { foo: 1 })
|
|
|
|
|
|
|
+ it('works on both tags and causes', async function () {
|
|
|
|
|
+ // Here's the actual error.
|
|
|
|
|
+ function tryToFoo() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ throw Error('foo')
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ throw OError.tag(error, 'failed to foo', { foo: 1 })
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- // Inside another function that wraps it.
|
|
|
|
|
- function tryToBar() {
|
|
|
|
|
- try {
|
|
|
|
|
- tryToFoo()
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- throw new OError('failed to bar').withCause(error)
|
|
|
|
|
|
|
+ // Inside another function that wraps it.
|
|
|
|
|
+ function tryToBar() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ tryToFoo()
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ throw new OError('failed to bar').withCause(error)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- // And it is in another try.
|
|
|
|
|
- try {
|
|
|
|
|
|
|
+ // And it is in another try.
|
|
|
try {
|
|
try {
|
|
|
- tryToBar()
|
|
|
|
|
- expect.fail('should have thrown')
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ tryToBar()
|
|
|
|
|
+ expect.fail('should have thrown')
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ throw OError.tag(error, 'failed to bat', { bat: 1 })
|
|
|
|
|
+ }
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
- throw OError.tag(error, 'failed to bat', { bat: 1 })
|
|
|
|
|
- }
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- // We catch the wrapping error.
|
|
|
|
|
- expectError(error, {
|
|
|
|
|
- name: 'OError',
|
|
|
|
|
- klass: OError,
|
|
|
|
|
- message: 'OError: failed to bar',
|
|
|
|
|
- firstFrameRx: /tryToBar/,
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ // We catch the wrapping error.
|
|
|
|
|
+ expectError(error, {
|
|
|
|
|
+ name: 'OError',
|
|
|
|
|
+ klass: OError,
|
|
|
|
|
+ message: 'OError: failed to bar',
|
|
|
|
|
+ firstFrameRx: /tryToBar/,
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- // But the stack contains all of the errors and tags.
|
|
|
|
|
- expectFullStackWithoutStackFramesToEqual(error, [
|
|
|
|
|
- 'OError: failed to bar',
|
|
|
|
|
- 'TaggedError: failed to bat',
|
|
|
|
|
- 'caused by:',
|
|
|
|
|
- ' Error: foo',
|
|
|
|
|
- ' TaggedError: failed to foo',
|
|
|
|
|
- ])
|
|
|
|
|
-
|
|
|
|
|
- // The info from the wrapped cause should be picked up for logging.
|
|
|
|
|
- expect(OError.getFullInfo(error)).to.eql({ bat: 1, foo: 1 })
|
|
|
|
|
-
|
|
|
|
|
- // But it should still be recorded.
|
|
|
|
|
- expect(OError.getFullInfo(error.cause)).to.eql({ foo: 1 })
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // But the stack contains all of the errors and tags.
|
|
|
|
|
+ expectFullStackWithoutStackFramesToEqual(error, [
|
|
|
|
|
+ 'OError: failed to bar',
|
|
|
|
|
+ 'TaggedError: failed to bat',
|
|
|
|
|
+ 'caused by:',
|
|
|
|
|
+ ' Error: foo',
|
|
|
|
|
+ ' TaggedError: failed to foo',
|
|
|
|
|
+ ])
|
|
|
|
|
+
|
|
|
|
|
+ // The info from the wrapped cause should be picked up for logging.
|
|
|
|
|
+ expect(OError.getFullInfo(error)).to.eql({ bat: 1, foo: 1 })
|
|
|
|
|
+
|
|
|
|
|
+ // But it should still be recorded.
|
|
|
|
|
+ expect(OError.getFullInfo(error.cause)).to.eql({ foo: 1 })
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|