Skip to content

Commit ad84130

Browse files
committed
add function to track whether an exception has been seen
1 parent 84a6dc0 commit ad84130

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

packages/utils/src/misc.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { Event, StackFrame } from '@sentry/types';
33

44
import { getGlobalObject } from './global';
5+
import { logger } from './logger';
56
import { snipLine } from './string';
67

78
/**
@@ -241,3 +242,35 @@ export function stripUrlQueryAndFragment(urlPath: string): string {
241242
// eslint-disable-next-line no-useless-escape
242243
return urlPath.split(/[\?#]/, 1)[0];
243244
}
245+
246+
/**
247+
* Checks whether or not we've already captured the given exception (note: not an identical exception - the very object
248+
* in question), and marks it captured if not.
249+
*
250+
* Sometimes an error gets captured by more than one mechanism. (This happens, for example, in frameworks where we
251+
* intercept thrown errors, capture them, and then rethrow them so that the framework can handle them however it
252+
* normally would, which may or may not lead to them being caught again by something like the global error handler.)
253+
* This prevents us from actually recording it twice.
254+
*
255+
* @param Any non-primitive (can use {@link: Object.objectify} to ensure this is the case)
256+
* @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)
257+
*/
258+
export function checkOrSetAlreadyCaught(exception: unknown): boolean {
259+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
260+
if ((exception as any).__sentry_captured__) {
261+
logger.log("Not capturing exception because it's already been captured.");
262+
return true;
263+
}
264+
265+
try {
266+
// set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the
267+
// `ExtraErrorData` integration
268+
Object.defineProperty(exception, '__sentry_captured__', {
269+
value: true,
270+
});
271+
} catch (err) {
272+
// `exception` is a primitive, so we can't mark it seen
273+
}
274+
275+
return false;
276+
}

0 commit comments

Comments
 (0)