From f44791049a762fbce777b03e9d930fba0c0c6570 Mon Sep 17 00:00:00 2001 From: pylixonly <82711525+pylixonly@users.noreply.github.com> Date: Mon, 21 Oct 2024 17:37:07 +0800 Subject: [PATCH] feat: port ErrorBoundary from dev --- src/core/debug/patches/patchErrorBoundary.tsx | 21 ++ .../components/ErrorBoundaryScreen.tsx | 52 +++++ src/core/ui/reporter/components/ErrorCard.tsx | 44 ++++ .../components/ErrorComponentStackCard.tsx | 53 +++++ .../components/ErrorDetailsActionSheet.tsx | 20 ++ .../ui/reporter/components/ErrorStackCard.tsx | 63 ++++++ src/core/ui/reporter/utils/isStack.tsx | 6 + .../ui/reporter/utils/parseComponentStack.tsx | 3 + src/core/ui/reporter/utils/parseErrorStack.ts | 202 ++++++++++++++++++ src/index.ts | 4 +- src/lib/ui/components/ErrorBoundary.tsx | 40 +--- src/lib/ui/safeMode.tsx | 149 ------------- src/lib/ui/sheets.ts | 3 +- 13 files changed, 475 insertions(+), 185 deletions(-) create mode 100644 src/core/debug/patches/patchErrorBoundary.tsx create mode 100644 src/core/ui/reporter/components/ErrorBoundaryScreen.tsx create mode 100644 src/core/ui/reporter/components/ErrorCard.tsx create mode 100644 src/core/ui/reporter/components/ErrorComponentStackCard.tsx create mode 100644 src/core/ui/reporter/components/ErrorDetailsActionSheet.tsx create mode 100644 src/core/ui/reporter/components/ErrorStackCard.tsx create mode 100644 src/core/ui/reporter/utils/isStack.tsx create mode 100644 src/core/ui/reporter/utils/parseComponentStack.tsx create mode 100644 src/core/ui/reporter/utils/parseErrorStack.ts delete mode 100644 src/lib/ui/safeMode.tsx diff --git a/src/core/debug/patches/patchErrorBoundary.tsx b/src/core/debug/patches/patchErrorBoundary.tsx new file mode 100644 index 0000000..ccab32a --- /dev/null +++ b/src/core/debug/patches/patchErrorBoundary.tsx @@ -0,0 +1,21 @@ +import ErrorBoundaryScreen from "@core/ui/reporter/components/ErrorBoundaryScreen"; +import { after } from "@lib/api/patcher"; +import { _lazyContextSymbol } from "@metro/lazy"; +import { LazyModuleContext } from "@metro/types"; +import { findByNameLazy } from "@metro/wrappers"; + +function getErrorBoundaryContext() { + const ctxt: LazyModuleContext = findByNameLazy("ErrorBoundary")[_lazyContextSymbol]; + return new Promise(resolve => ctxt.getExports(exp => resolve(exp.prototype))); +} + +export default function patchErrorBoundary() { + return after.await("render", getErrorBoundaryContext(), function (this: any) { + if (!this.state.error) return; + + return this.setState({ info: null, error: null })} + />; + }); +} diff --git a/src/core/ui/reporter/components/ErrorBoundaryScreen.tsx b/src/core/ui/reporter/components/ErrorBoundaryScreen.tsx new file mode 100644 index 0000000..b6beffe --- /dev/null +++ b/src/core/ui/reporter/components/ErrorBoundaryScreen.tsx @@ -0,0 +1,52 @@ +import { hasStack, isComponentStack } from "@core/ui/reporter/utils/isStack"; +import { getDebugInfo, toggleSafeMode } from "@lib/api/debug"; +import { BundleUpdaterManager } from "@lib/api/native/modules"; +import { settings } from "@lib/api/settings"; +import { Codeblock, ErrorBoundary } from "@lib/ui/components"; +import { createStyles } from "@lib/ui/styles"; +import { tokens } from "@metro/common"; +import { Button, Card, SafeAreaView, Text } from "@metro/common/components"; +import { ScrollView, View } from "react-native"; + +import ErrorComponentStackCard from "./ErrorComponentStackCard"; +import ErrorStackCard from "./ErrorStackCard"; + +const useStyles = createStyles({ + container: { + flex: 1, + backgroundColor: tokens.colors.BACKGROUND_PRIMARY, + paddingHorizontal: 16, + height: "100%", + padding: 8, + gap: 12 + } +}); + + +export default function ErrorBoundaryScreen(props: { + error: Error; + rerender: () => void; +}) { + const styles = useStyles(); + const debugInfo = getDebugInfo(); + + return + + + Uh oh. + A crash occured while rendering a component. This could be caused by a plugin, Bunny or Discord itself. + {debugInfo.os.name}; {debugInfo.discord.build} ({debugInfo.discord.version}); {debugInfo.bunny.version} + + + {props.error.message} + {hasStack(props.error) && } + {isComponentStack(props.error) ? : null} + + +