react-native-filament
Version:
A real-time physically based 3D rendering engine for React Native
50 lines (45 loc) • 1.63 kB
text/typescript
import { Worklets } from 'react-native-worklets-core'
/**
* Report an error to react native's `ErrorUtils` if available, or log to console otherwise.
*/
export function reportError(error: unknown, fatal: boolean): void {
// @ts-expect-error this is defined by react-native.
if (global.ErrorUtils != null) {
if (fatal) {
// @ts-expect-error this is defined by react-native.
global.ErrorUtils.reportFatalError(error)
} else {
// @ts-expect-error this is defined by react-native.
global.ErrorUtils.reportError(error)
}
} else {
console.error(`An unknown Filament error occurred!`, error)
}
}
const throwErrorOnJS = Worklets.createRunOnJS((message: string, stack: string | undefined, fatal: boolean) => {
const error = new Error()
error.message = message
error.stack = stack
error.name = 'Filament Error'
// @ts-expect-error this is react-native specific
error.jsEngine = 'Filament'
// From react-native:
reportError(error, fatal)
})
export const reportWorkletError = (error: unknown, fatal = true): void => {
'worklet'
const safeError = error as Error | undefined
const message = safeError != null && 'message' in safeError ? safeError.message : 'Filament threw an error.'
throwErrorOnJS(message, safeError?.stack, fatal)
}
export const wrapWithErrorHandler = <T extends (...args: any[]) => any>(callback: T): ((...args: Parameters<T>) => ReturnType<T>) => {
return (...args: Parameters<T>): ReturnType<T> => {
'worklet'
try {
return callback(...args)
} catch (error) {
reportWorkletError(error)
throw error
}
}
}