summaryrefslogtreecommitdiff
path: root/frontend/src/errorboundary-hook.tsx
diff options
context:
space:
mode:
authorAAGaming <aagaming@riseup.net>2024-05-25 19:14:54 -0400
committerAAGaming <aagaming@riseup.net>2024-05-25 19:14:54 -0400
commita84a13c76d99f1e6f4505d43108a4111749e5035 (patch)
treee2826700cd371e6590818047551028d8179389bf /frontend/src/errorboundary-hook.tsx
parent96cc72f2ca25ccb312b68a29aca755bb7df660ed (diff)
downloaddecky-loader-a84a13c76d99f1e6f4505d43108a4111749e5035.tar.gz
decky-loader-a84a13c76d99f1e6f4505d43108a4111749e5035.zip
Custom error handler and some misc fixes
Diffstat (limited to 'frontend/src/errorboundary-hook.tsx')
-rw-r--r--frontend/src/errorboundary-hook.tsx69
1 files changed, 69 insertions, 0 deletions
diff --git a/frontend/src/errorboundary-hook.tsx b/frontend/src/errorboundary-hook.tsx
new file mode 100644
index 00000000..175b3ff6
--- /dev/null
+++ b/frontend/src/errorboundary-hook.tsx
@@ -0,0 +1,69 @@
+import { Patch, callOriginal, findModuleExport, replacePatch } from '@decky/ui';
+
+import DeckyErrorBoundary from './components/DeckyErrorBoundary';
+import Logger from './logger';
+
+declare global {
+ interface Window {
+ __ERRORBOUNDARY_HOOK_INSTANCE: any;
+ }
+}
+
+class ErrorBoundaryHook extends Logger {
+ private errorBoundaryPatch?: Patch;
+
+ constructor() {
+ super('ErrorBoundaryHook');
+
+ this.log('Initialized');
+ window.__ERRORBOUNDARY_HOOK_INSTANCE?.deinit?.();
+ window.__ERRORBOUNDARY_HOOK_INSTANCE = this;
+ }
+
+ init() {
+ // valve writes only the sanest of code
+ const exp = /^\(\)=>\(.\|\|.\(new .\),.\)$/;
+ const initErrorReportingStore = findModuleExport(
+ (e) => typeof e == 'function' && e?.toString && exp.test(e.toString()),
+ );
+
+ if (!initErrorReportingStore) {
+ this.error('could not find initErrorReportingStore! error boundary hook disabled!');
+ return;
+ }
+ // will replace the existing one for us seemingly? doesnt matter anyway lol
+ const errorReportingStore = initErrorReportingStore();
+
+ // NUH UH.
+ Object.defineProperty(Object.getPrototypeOf(errorReportingStore), 'reporting_enabled', {
+ get: () => false,
+ });
+ errorReportingStore.m_bEnabled = false;
+
+ // @ts-ignore
+ // window.errorStore = errorReportingStore;
+
+ const ValveErrorBoundary = findModuleExport(
+ (e) => e.InstallErrorReportingStore && e?.prototype?.Reset && e?.prototype?.componentDidCatch,
+ );
+ if (!ValveErrorBoundary) {
+ this.error('could not find ValveErrorBoundary');
+ return;
+ }
+
+ this.errorBoundaryPatch = replacePatch(ValveErrorBoundary.prototype, 'render', function (this: any) {
+ if (this.state.error) {
+ return (
+ <DeckyErrorBoundary error={this.state.error} errorKey={this.state.errorKey} reset={() => this.Reset()} />
+ );
+ }
+ return callOriginal;
+ });
+ }
+
+ deinit() {
+ this.errorBoundaryPatch?.unpatch();
+ }
+}
+
+export default ErrorBoundaryHook;