From 3b225c1d5ed775c07d6b9bc2519d4c12dc34c0aa Mon Sep 17 00:00:00 2001 From: goon-foss Date: Wed, 22 Jul 2026 09:11:11 +0200 Subject: [PATCH] fix(mobile): guard Alert.alert behind AppState==='active' (kill DeadObjectException) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sentry ddec9d6b (fatal, Android): RuntimeException 'Adding window failed' / DeadObjectException gdy RN Alert (natywny DialogFragment) pokazuje się przez WindowManager.addView na oknie activity które leci w tło / jest ubijane (martwy binder). Trigger: alert z async handlera (np. 'Update available' na boocie) odpalony gdy user zbackgroundował apkę. Fix: globalny patch Alert.alert (src/lib/alertGuard, side-effect import w App.tsx) — no-op gdy AppState.currentState !== 'active'. Obejmuje wszystkie ~56 call-site bez owijania każdego. Transientowe alerty w tle i tak bez sensu; update wróci przy następnym foregroundzie. --- mobile/App.tsx | 3 +++ mobile/src/changelog.ts | 7 +++++++ mobile/src/lib/alertGuard.ts | 26 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 mobile/src/lib/alertGuard.ts diff --git a/mobile/App.tsx b/mobile/App.tsx index 7745614..719ec77 100644 --- a/mobile/App.tsx +++ b/mobile/App.tsx @@ -1,6 +1,9 @@ // MUST be the first import for react-navigation 7 + reanimated/gesture-handler // in release builds. Otherwise Hermes-bundled APK boots to a white screen. import 'react-native-gesture-handler'; +// Guard na Alert.alert (AppState==='active') — kill crasha "Adding window failed" / +// DeadObjectException gdy dialog leci na martwym oknie (Sentry ddec9d6b). Side-effect. +import './src/lib/alertGuard'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import * as Sentry from '@sentry/react-native'; diff --git a/mobile/src/changelog.ts b/mobile/src/changelog.ts index 433a5ed..2a38e4f 100644 --- a/mobile/src/changelog.ts +++ b/mobile/src/changelog.ts @@ -16,6 +16,13 @@ export type ChangelogEntry = { }; export const CHANGELOG: ChangelogEntry[] = [ + { + id: '2026-07-22', + date: 'July 2026', + items: [ + 'Fixed a rare crash that could happen when a pop-up (like the update prompt) tried to appear just as the app was being sent to the background.', + ], + }, { id: '2026-07-21', date: 'July 2026', diff --git a/mobile/src/lib/alertGuard.ts b/mobile/src/lib/alertGuard.ts new file mode 100644 index 0000000..f72d4e0 --- /dev/null +++ b/mobile/src/lib/alertGuard.ts @@ -0,0 +1,26 @@ +/** + * Fix natywnego crasha "RuntimeException: Adding window failed" / DeadObjectException + * (Sentry issue ddec9d6b, fatal, Android). RN `Alert.alert` pokazuje natywny + * DialogFragment przez WindowManager.addView. Gdy activity leci w tło albo jest + * ubijane (binder do WindowManagera martwy) w momencie `Dialog.show()`, add-window + * rzuca DeadObjectException → fatal crash. Typowy trigger: alert z async handlera + * (np. "Update available" na boocie, błąd playbacku/resolve) odpalony gdy user zdążył + * zbackgroundować apkę. + * + * Guard: nie pokazuj dialogu gdy apka NIE jest na wierzchu ('active'). Transientowe + * alerty w tle i tak nie mają sensu (user nie patrzy), a ważne (update) wrócą przy + * następnym foregroundzie/launchu. Patch globalny na Alert.alert — obejmuje WSZYSTKIE + * wywołania (obecne i przyszłe, też z bibliotek) bez owijania ~56 call-site'ów. + * + * Import jako side-effect NA GÓRZE App.tsx, przed pierwszym możliwym Alertem. + */ +import { Alert, AppState } from 'react-native'; + +const _origAlert = Alert.alert.bind(Alert); + +(Alert as { alert: typeof Alert.alert }).alert = (( + ...args: Parameters +) => { + if (AppState.currentState !== 'active') return; + return _origAlert(...args); +}) as typeof Alert.alert;