|
1 | 1 | import { log } from '@hawk.so/core'; |
| 2 | +import Sanitizer from '../modules/sanitizer'; |
2 | 3 |
|
3 | 4 | /** |
4 | 5 | * Symbol to mark error as processed by Hawk |
@@ -44,3 +45,38 @@ export function markErrorAsProcessed(error: unknown): void { |
44 | 45 | log('Failed to mark error as processed', 'error', e); |
45 | 46 | } |
46 | 47 | } |
| 48 | + |
| 49 | +/** |
| 50 | + * Extracts and normalizes error from ErrorEvent or PromiseRejectionEvent |
| 51 | + * |
| 52 | + * @param event - The error or promise rejection event |
| 53 | + */ |
| 54 | +export function getErrorFromEvent(event: ErrorEvent | PromiseRejectionEvent): Error | string { |
| 55 | + /** |
| 56 | + * Promise rejection reason is recommended to be an Error, but it can be a string: |
| 57 | + * - Promise.reject(new Error('Reason message')) ——— recommended |
| 58 | + * - Promise.reject('Reason message') |
| 59 | + */ |
| 60 | + let error = (event as ErrorEvent).error || (event as PromiseRejectionEvent).reason; |
| 61 | + |
| 62 | + /** |
| 63 | + * Case when error triggered in external script |
| 64 | + * We can't access event error object because of CORS |
| 65 | + * Event message will be 'Script error.' |
| 66 | + */ |
| 67 | + if (event instanceof ErrorEvent && error === undefined) { |
| 68 | + error = (event as ErrorEvent).message; |
| 69 | + } |
| 70 | + |
| 71 | + /** |
| 72 | + * Case when error rejected with an object |
| 73 | + * Using a string instead of wrapping in Error is more natural, |
| 74 | + * it doesn't fake the backtrace, also prefix added for dashboard readability |
| 75 | + */ |
| 76 | + if (error instanceof Object && !(error instanceof Error) && event instanceof PromiseRejectionEvent) { |
| 77 | + // Extra sanitize is needed to handle objects with circular references before JSON.stringify |
| 78 | + error = `Promise rejected with ${JSON.stringify(Sanitizer.sanitize(error))}`; |
| 79 | + } |
| 80 | + |
| 81 | + return Sanitizer.sanitize(error); |
| 82 | +} |
0 commit comments