Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions packages/react-native-reanimated/src/errors.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
/* eslint-disable reanimated/use-reanimated-error */
'use strict';

import { createCustomError, registerCustomError } from 'react-native-worklets';

export const ReanimatedError = createCustomError('Reanimated');

const ReanimatedErrorConstructor = ReanimatedError;
function ReanimatedErrorConstructor(message: string): ReanimatedError {
'worklet';
const prefix = '[Reanimated]';
const errorInstance = new Error(message ? `${prefix} ${message}` : prefix);
errorInstance.name = 'ReanimatedError';
return errorInstance as ReanimatedError;
}

/**
* Registers ReanimatedError in the global scope. Register only for Worklet
* runtimes.
*/
export function registerReanimatedError() {
'worklet';
registerCustomError(ReanimatedErrorConstructor, 'Reanimated');
if (globalThis._WORKLET) {
globalThis.ReanimatedError =
ReanimatedErrorConstructor as IReanimatedErrorConstructor;
}
}

export const ReanimatedError =
ReanimatedErrorConstructor as IReanimatedErrorConstructor;

export interface IReanimatedErrorConstructor extends Error {
new (message?: string): ReanimatedError;
(message?: string): ReanimatedError;
readonly prototype: ReanimatedError;
}

export type ReanimatedError = Error & { name: 'Reanimated' }; // signed type
2 changes: 2 additions & 0 deletions packages/react-native-reanimated/src/privateGlobals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {
ShadowNodeWrapper,
StyleProps,
} from './commonTypes';
import type { IReanimatedErrorConstructor } from './errors';
import type { FrameCallbackRegistryUI } from './frameCallback/FrameCallbackRegistryUI';
import type { AnimatedStyle } from './helperTypes';
import type { LayoutAnimationsManager } from './layoutReanimation/animationsManager';
Expand Down Expand Up @@ -101,4 +102,5 @@ declare global {
value: T,
nativeStateSource?: object
) => FlatShareableRef<T>;
var ReanimatedError: IReanimatedErrorConstructor;
}
34 changes: 27 additions & 7 deletions packages/react-native-worklets/src/WorkletsError.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
/* eslint-disable reanimated/use-worklets-error */
'use strict';

import { createCustomError, registerCustomError } from './errors';

export const WorkletsError = createCustomError('Worklets');

// To capture it in a the registering worklet's closure.
const WorkletsErrorConstructor = WorkletsError;
function WorkletsErrorConstructor(message?: string): WorkletsError {
'worklet';
const prefix = '[Worklets]';
const errorInstance = new Error(message ? `${prefix} ${message}` : prefix);
errorInstance.name = `WorkletsError`;
return errorInstance as WorkletsError;
}

/**
* Registers WorkletsError in the global scope. Register only for Worklet
* runtimes.
*/
export function registerWorkletsError() {
'worklet';
registerCustomError(WorkletsErrorConstructor, 'Worklets');
if (globalThis._WORKLET) {
globalThis.WorkletsError =
WorkletsErrorConstructor as IWorkletsErrorConstructor;
}
}

export const WorkletsError =
WorkletsErrorConstructor as IWorkletsErrorConstructor;

export type WorkletsError = Error & { name: 'Worklets' }; // signed type

export interface IWorkletsErrorConstructor extends Error {
new (message?: string): WorkletsError;
(message?: string): WorkletsError;
readonly prototype: WorkletsError;
}
40 changes: 0 additions & 40 deletions packages/react-native-worklets/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,6 @@

import type { WorkletStackDetails } from './workletTypes';

export type CustomError<TName extends string> = Error & { name: TName }; // signed type

export interface CustomErrorConstructor<TName extends string> extends Error {
new (message?: string): CustomError<TName>;
(message?: string): CustomError<TName>;
readonly prototype: CustomError<TName>;
}

export function createCustomError<TName extends string>(
name: TName
): CustomErrorConstructor<TName> {
const constructor = function CustomError(message?: string) {
'worklet';
const prefix = `[${name}]`;
// eslint-disable-next-line reanimated/use-worklets-error
const errorInstance = new Error(message ? `${prefix} ${message}` : prefix);
errorInstance.name = `${name}Error`;
return errorInstance;
};

Object.defineProperty(constructor, 'name', { value: `${name}Error` });

return constructor as CustomErrorConstructor<TName>;
}

/** Registers custom errors in global scope. Use it only for Worklet runtimes. */
export function registerCustomError<TName extends string>(
constructor: CustomErrorConstructor<TName>,
name: TName
) {
'worklet';
if (!globalThis._WORKLET) {
// eslint-disable-next-line reanimated/use-worklets-error
throw new Error(
'[Worklets] registerCustomError() must be called on a Worklet runtime'
);
}
(global as Record<string, unknown>)[`${name}Error`] = constructor;
}

const _workletStackDetails = new Map<number, WorkletStackDetails>();

export function registerWorkletStackDetails(
Expand Down
2 changes: 0 additions & 2 deletions packages/react-native-worklets/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { WorkletsModule } from './WorkletsModule';
// universal source of truth for it.
initializeUIRuntime(WorkletsModule);

export type { CustomError } from './errors';
export { createCustomError, registerCustomError } from './errors';
export type { LoggerConfig } from './logger';
export {
logger,
Expand Down
2 changes: 2 additions & 0 deletions packages/react-native-worklets/src/privateGlobals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// This file works by accident - currently Builder Bob doesn't move `.d.ts` files to output types.
// If it ever breaks, we should address it so we'd not pollute the user's global namespace.
import type { callGuardDEV } from './initializers';
import type { IWorkletsErrorConstructor } from './WorkletsError';
import type { WorkletsModuleProxy } from './WorkletsModule';

declare global {
Expand Down Expand Up @@ -40,4 +41,5 @@ declare global {
worklet: ShareableRef<() => void>
) => void;
var _microtaskQueueFinalizers: (() => void)[];
var WorkletsError: IWorkletsErrorConstructor;
}