error-reporter.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // Conditionally enable Sentry based on whether the DSN token is set
  2. const reporterPromise = window.ExposedSettings.sentryDsn
  3. ? sentryReporter()
  4. : nullReporter()
  5. function sentryReporter() {
  6. return (
  7. import(/* webpackMode: "eager" */ '@sentry/browser')
  8. .then(Sentry => {
  9. let eventCount = 0
  10. Sentry.init({
  11. dsn: window.ExposedSettings.sentryDsn,
  12. release: window.ExposedSettings.sentryRelease,
  13. autoSessionTracking: false,
  14. // Ignore errors unless they come from our origins
  15. // Adapted from: https://docs.sentry.io/platforms/javascript/#decluttering-sentry
  16. whitelistUrls: [
  17. new RegExp(window.ExposedSettings.sentryAllowedOriginRegex),
  18. ],
  19. ignoreErrors: [
  20. // Ignore very noisy error
  21. 'SecurityError: Permission denied to access property "pathname" on cross-origin object',
  22. // Ignore unhandled error that is "expected" - see https://github.com/overleaf/issues/issues/3321
  23. /^Missing PDF/,
  24. // Ignore "expected" error from aborted fetch - see https://github.com/overleaf/issues/issues/3321
  25. /^AbortError/,
  26. // Ignore spurious error from Ace internals - see https://github.com/overleaf/issues/issues/3321
  27. 'ResizeObserver loop limit exceeded',
  28. 'ResizeObserver loop completed with undelivered notifications.',
  29. ],
  30. beforeSend(event) {
  31. // Limit number of events sent to Sentry to 100 events "per page load",
  32. // (i.e. the cap will be reset if the page is reloaded). This prevent
  33. // hitting their server-side event cap.
  34. eventCount++
  35. if (eventCount > 100) {
  36. return null // Block the event from sending
  37. } else {
  38. return event
  39. }
  40. },
  41. })
  42. Sentry.setUser({ id: window.user_id })
  43. return Sentry
  44. })
  45. // If Sentry fails to load, use the null reporter instead
  46. .catch(error => {
  47. console.error(error)
  48. return nullReporter()
  49. })
  50. )
  51. }
  52. function nullReporter() {
  53. return Promise.resolve({
  54. captureException: console.error,
  55. captureMessage: console.error,
  56. })
  57. }
  58. export function captureException(...args) {
  59. reporterPromise.then(reporter => reporter.captureException(...args))
  60. }
  61. export function captureMessage(...args) {
  62. reporterPromise.then(reporter => reporter.captureMessage(...args))
  63. }