From a84a13c76d99f1e6f4505d43108a4111749e5035 Mon Sep 17 00:00:00 2001
From: AAGaming <aagaming@riseup.net>
Date: Sat, 25 May 2024 19:14:54 -0400
Subject: Custom error handler and some misc fixes

---
 frontend/src/errorboundary-hook.tsx | 69 +++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 frontend/src/errorboundary-hook.tsx

(limited to 'frontend/src/errorboundary-hook.tsx')

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;
-- 
cgit v1.2.3

