UNPKG

1.88 kBPlain TextView Raw
1'use strict';
2import type { WorkletStackDetails } from './commonTypes';
3
4const _workletStackDetails = new Map<number, WorkletStackDetails>();
5
6export function registerWorkletStackDetails(
7 hash: number,
8 stackDetails: WorkletStackDetails
9) {
10 _workletStackDetails.set(hash, stackDetails);
11}
12
13function getBundleOffset(error: Error): [string, number, number] {
14 const frame = error.stack?.split('\n')?.[0];
15 if (frame) {
16 const parsedFrame = /@([^@]+):(\d+):(\d+)/.exec(frame);
17 if (parsedFrame) {
18 const [, file, line, col] = parsedFrame;
19 return [file, Number(line), Number(col)];
20 }
21 }
22 return ['unknown', 0, 0];
23}
24
25function processStack(stack: string): string {
26 const workletStackEntries = stack.match(/worklet_(\d+):(\d+):(\d+)/g);
27 let result = stack;
28 workletStackEntries?.forEach((match) => {
29 const [, hash, origLine, origCol] = match.split(/:|_/).map(Number);
30 const errorDetails = _workletStackDetails.get(hash);
31 if (!errorDetails) {
32 return;
33 }
34 const [error, lineOffset, colOffset] = errorDetails;
35 const [bundleFile, bundleLine, bundleCol] = getBundleOffset(error);
36 const line = origLine + bundleLine + lineOffset;
37 const col = origCol + bundleCol + colOffset;
38
39 result = result.replace(match, `${bundleFile}:${line}:${col}`);
40 });
41 return result;
42}
43
44export function reportFatalErrorOnJS({
45 message,
46 stack,
47}: {
48 message: string;
49 stack?: string;
50}) {
51 const error = new Error();
52 error.message = message;
53 error.stack = stack ? processStack(stack) : undefined;
54 error.name = 'ReanimatedError';
55 // @ts-ignore React Native's ErrorUtils implementation extends the Error type with jsEngine field
56 error.jsEngine = 'reanimated';
57 // @ts-ignore the reportFatalError method is an internal method of ErrorUtils not exposed in the type definitions
58 global.ErrorUtils.reportFatalError(error);
59}