(errorEvent, prop, cb)
| 25 | } |
| 26 | |
| 27 | function catchWindowErrors(errorEvent, prop, cb) { |
| 28 | let userErrorListenerCount = 0 |
| 29 | function throwUnhandlerError(e) { |
| 30 | if (userErrorListenerCount === 0 && e[prop] != null) { |
| 31 | cb(e) |
| 32 | } |
| 33 | else { |
| 34 | // `ErrorEvent` doesn't necessary have `ErrorEvent.error` defined |
| 35 | // but some has `ErrorEvent.message` defined, e.g. ResizeObserver error. |
| 36 | // https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent/error |
| 37 | // https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver#observation_errors |
| 38 | console.error(e.message ? new Error(e.message) : e) |
| 39 | } |
| 40 | } |
| 41 | const addEventListener = window.addEventListener.bind(window) |
| 42 | const removeEventListener = window.removeEventListener.bind(window) |
| 43 | window.addEventListener(errorEvent, throwUnhandlerError) |
| 44 | window.addEventListener = function (...args) { |
| 45 | if (args[0] === errorEvent) { |
| 46 | userErrorListenerCount++ |
| 47 | } |
| 48 | return addEventListener.apply(this, args) |
| 49 | } |
| 50 | window.removeEventListener = function (...args) { |
| 51 | if (args[0] === errorEvent && userErrorListenerCount) { |
| 52 | userErrorListenerCount-- |
| 53 | } |
| 54 | return removeEventListener.apply(this, args) |
| 55 | } |
| 56 | return function clearErrorHandlers() { |
| 57 | window.removeEventListener(errorEvent, throwUnhandlerError) |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | function registerUnexpectedErrors() { |
| 62 | const offError = catchWindowErrors('error', 'error', event => |
no test coverage detected