sentry-manager-tests.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. const Path = require('path')
  2. const SandboxedModule = require('sandboxed-module')
  3. const { expect } = require('chai')
  4. const sinon = require('sinon')
  5. const MODULE_PATH = Path.join(__dirname, '../../sentry-manager.js')
  6. describe('SentryManager', function () {
  7. beforeEach(function () {
  8. this.clock = sinon.useFakeTimers(Date.now())
  9. this.Sentry = {
  10. init: sinon.stub(),
  11. captureException: sinon.stub(),
  12. }
  13. this.SentryManager = SandboxedModule.require(MODULE_PATH, {
  14. requires: {
  15. '@sentry/node': this.Sentry,
  16. },
  17. })
  18. this.sentryManager = new this.SentryManager('test_dsn')
  19. })
  20. afterEach(function () {
  21. this.clock.restore()
  22. })
  23. describe('captureExceptionRateLimited', function () {
  24. it('should report a single error to sentry', function () {
  25. this.sentryManager.captureExceptionRateLimited({ foo: 'bar' }, 'message')
  26. expect(this.Sentry.captureException).to.have.been.calledOnce
  27. })
  28. it('should report the same error to sentry only once', function () {
  29. const error1 = new Error('this is the error')
  30. this.sentryManager.captureExceptionRateLimited(
  31. { foo: error1 },
  32. 'first message'
  33. )
  34. this.sentryManager.captureExceptionRateLimited(
  35. { bar: error1 },
  36. 'second message'
  37. )
  38. expect(this.Sentry.captureException).to.have.been.calledOnce
  39. })
  40. it('should report two different errors to sentry individually', function () {
  41. const error1 = new Error('this is the error')
  42. const error2 = new Error('this is the error')
  43. this.sentryManager.captureExceptionRateLimited(
  44. { foo: error1 },
  45. 'first message'
  46. )
  47. this.sentryManager.captureExceptionRateLimited(
  48. { bar: error2 },
  49. 'second message'
  50. )
  51. expect(this.Sentry.captureException).to.have.been.calledTwice
  52. })
  53. it('for multiple errors should only report a maximum of 5 errors to sentry', function () {
  54. for (let i = 0; i < 10; i++) {
  55. this.sentryManager.captureExceptionRateLimited(
  56. { foo: 'bar' },
  57. 'message'
  58. )
  59. }
  60. expect(this.Sentry.captureException).to.have.callCount(5)
  61. })
  62. it('for multiple errors with a minute delay should report 10 errors to sentry', function () {
  63. for (let i = 0; i < 10; i++) {
  64. this.sentryManager.captureExceptionRateLimited(
  65. { foo: 'bar' },
  66. 'message'
  67. )
  68. }
  69. expect(this.Sentry.captureException).to.have.callCount(5)
  70. // allow a minute to pass
  71. this.clock.tick(61 * 1000)
  72. for (let i = 0; i < 10; i++) {
  73. this.sentryManager.captureExceptionRateLimited(
  74. { foo: 'bar' },
  75. 'message'
  76. )
  77. }
  78. expect(this.Sentry.captureException).to.have.callCount(10)
  79. })
  80. })
  81. describe('captureException', function () {
  82. it('should remove the path from fs errors', function () {
  83. const fsError = new Error(
  84. "Error: ENOENT: no such file or directory, stat '/tmp/3279b8d0-da10-11e8-8255-efd98985942b'"
  85. )
  86. fsError.path = '/tmp/3279b8d0-da10-11e8-8255-efd98985942b'
  87. this.sentryManager.captureException({ err: fsError }, 'message', 'error')
  88. expect(this.Sentry.captureException).to.have.been.calledWith(
  89. sinon.match.has(
  90. 'message',
  91. 'Error: ENOENT: no such file or directory, stat'
  92. )
  93. )
  94. })
  95. describe('reportedToSentry', function () {
  96. it('should mark the error as reported to sentry', function () {
  97. const err = new Error()
  98. this.sentryManager.captureException({ err }, 'message')
  99. expect(this.Sentry.captureException).to.have.been.called
  100. expect(err.reportedToSentry).to.equal(true)
  101. })
  102. it('should mark two errors as reported to sentry', function () {
  103. const err1 = new Error()
  104. const err2 = new Error()
  105. this.sentryManager.captureException({ err: err1, err2 }, 'message')
  106. expect(this.Sentry.captureException).to.have.been.called
  107. expect(err1.reportedToSentry).to.equal(true)
  108. expect(err2.reportedToSentry).to.equal(true)
  109. })
  110. it('should not mark arbitrary objects as reported to sentry', function () {
  111. const err = new Error()
  112. const ctx = { foo: 'bar' }
  113. this.sentryManager.captureException({ err, ctx }, 'message')
  114. expect(this.Sentry.captureException).to.have.been.called
  115. expect(ctx.reportedToSentry).not.to.exist
  116. })
  117. })
  118. })
  119. })