o-error.test.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. const { expect } = require('chai')
  2. const OError = require('..')
  3. const {
  4. expectError,
  5. expectFullStackWithoutStackFramesToEqual,
  6. } = require('./support')
  7. class CustomError1 extends OError {
  8. constructor() {
  9. super('failed to foo')
  10. }
  11. }
  12. class CustomError2 extends OError {
  13. constructor(customMessage) {
  14. super(customMessage || 'failed to bar')
  15. }
  16. }
  17. describe('OError', function () {
  18. it('can have an info object', function () {
  19. const err1 = new OError('foo', { foo: 1 })
  20. expect(err1.info).to.eql({ foo: 1 })
  21. const err2 = new OError('foo').withInfo({ foo: 2 })
  22. expect(err2.info).to.eql({ foo: 2 })
  23. })
  24. it('can have a cause', function () {
  25. const err1 = new OError('foo', { foo: 1 }, new Error('cause 1'))
  26. expect(err1.cause.message).to.equal('cause 1')
  27. const err2 = new OError('foo').withCause(new Error('cause 2'))
  28. expect(err2.cause.message).to.equal('cause 2')
  29. })
  30. it('accepts non-Error causes', function () {
  31. const err1 = new OError('foo', {}, 'not-an-error')
  32. expect(err1.cause).to.equal('not-an-error')
  33. const err2 = new OError('foo').withCause('not-an-error')
  34. expect(err2.cause).to.equal('not-an-error')
  35. })
  36. it('handles a custom error type with a cause', function () {
  37. function doSomethingBadInternally() {
  38. throw new Error('internal error')
  39. }
  40. function doSomethingBad() {
  41. try {
  42. doSomethingBadInternally()
  43. } catch (error) {
  44. throw new CustomError1().withCause(error)
  45. }
  46. }
  47. try {
  48. doSomethingBad()
  49. expect.fail('should have thrown')
  50. } catch (error) {
  51. expectError(error, {
  52. name: 'CustomError1',
  53. klass: CustomError1,
  54. message: 'CustomError1: failed to foo',
  55. firstFrameRx: /doSomethingBad/,
  56. })
  57. expect(OError.getFullInfo(error)).to.deep.equal({})
  58. expectFullStackWithoutStackFramesToEqual(error, [
  59. 'CustomError1: failed to foo',
  60. 'caused by:',
  61. ' Error: internal error',
  62. ])
  63. }
  64. })
  65. it('handles a custom error type with nested causes', function () {
  66. function doSomethingBadInternally() {
  67. throw new Error('internal error')
  68. }
  69. function doBar() {
  70. try {
  71. doSomethingBadInternally()
  72. } catch (error) {
  73. throw new CustomError2('failed to bar!').withCause(error)
  74. }
  75. }
  76. function doFoo() {
  77. try {
  78. doBar()
  79. } catch (error) {
  80. throw new CustomError1().withCause(error)
  81. }
  82. }
  83. try {
  84. doFoo()
  85. expect.fail('should have thrown')
  86. } catch (error) {
  87. expectError(error, {
  88. name: 'CustomError1',
  89. klass: CustomError1,
  90. message: 'CustomError1: failed to foo',
  91. firstFrameRx: /doFoo/,
  92. })
  93. expectFullStackWithoutStackFramesToEqual(error, [
  94. 'CustomError1: failed to foo',
  95. 'caused by:',
  96. ' CustomError2: failed to bar!',
  97. ' caused by:',
  98. ' Error: internal error',
  99. ])
  100. expect(OError.getFullInfo(error)).to.deep.equal({})
  101. }
  102. })
  103. })