feat: catch and report fatal initialization errors

This commit is contained in:
PalmDevs 2025-10-17 15:49:50 +07:00
parent e9f611e325
commit fbf2396d94
No known key found for this signature in database
GPG key ID: 6FAE8F8677ACA8BA
5 changed files with 31 additions and 23 deletions

View file

@ -1,5 +1,5 @@
export function getErrorStack(e: unknown) {
return e instanceof Error ? e.stack : String(e)
return e instanceof Error ? (e.stack ?? String(e)) : String(e)
}
export function getCurrentStack() {

View file

@ -131,7 +131,6 @@ export default async function build(dev = Dev, log = true) {
await bundle.write({
minify: 'dce-only',
exports: 'none',
esModule: false,
minifyInternalExports: true,
hoistTransitiveImports: false,

View file

@ -1,5 +1,16 @@
import { callBridgeMethod } from '@revenge-mod/modules/native'
import { getErrorStack } from '@revenge-mod/utils/error'
import { BuildEnvironment, FullVersion } from '~constants'
import type { Metro } from '@revenge-mod/modules/types'
// @ts-expect-error
globalThis.ErrorUtils = {
// RN JSI only requires these two properties:
// https://github.com/facebook/react-native/blob/802e1a7/packages/react-native/ReactCommon/cxxreact/ErrorUtils.h#L18-L19
reportError: onError,
reportFatalError: onError,
}
Object.defineProperty(globalThis, '__c', {
configurable: true,
set(clear: Metro.ClearFn) {
@ -12,3 +23,20 @@ Object.defineProperty(globalThis, '__c', {
import('./preinit')
},
})
export function onError(error: unknown) {
const stack = getErrorStack(error)
callBridgeMethod('revenge.alertError', [
stack,
`${FullVersion} (${BuildEnvironment})`,
])
nativeLoggingHook(`\u001b[31m${stack}\u001b[0m`, 2)
}
declare module '@revenge-mod/modules/native' {
export interface Methods {
'revenge.alertError': [[error: string, version: string], void]
}
}

View file

@ -3,7 +3,7 @@ import '@revenge-mod/react/init'
import '@revenge-mod/storage/init'
import { onRunApplication } from '@revenge-mod/react/native'
import { onError } from '~preinit'
import { onError } from '~index'
const unsub = onRunApplication(() => {
unsub()

View file

@ -5,9 +5,7 @@ import {
onModuleFirstRequired,
onModuleInitialized,
} from '@revenge-mod/modules/metro/subscriptions'
import { callBridgeMethod } from '@revenge-mod/modules/native'
import { getErrorStack } from '@revenge-mod/utils/error'
import { BuildEnvironment, FullVersion } from '~constants'
import { onError } from '~index'
const IndexModuleId = 0
@ -49,20 +47,3 @@ onModuleFirstRequired(IndexModuleId, function onIndexRequired() {
onError(e)
}
})
export function onError(error: unknown) {
const stack = getErrorStack(error) ?? String(error)
callBridgeMethod('revenge.alertError', [
stack,
`${FullVersion} (${BuildEnvironment})`,
])
nativeLoggingHook(`\u001b[31m${stack}\u001b[0m`, 2)
}
declare module '@revenge-mod/modules/native' {
export interface Methods {
'revenge.alertError': [[error: string, version: string], void]
}
}