fix(mobile): guard Alert.alert behind AppState==='active' (kill DeadObjectException)
Some checks are pending
Backend tests / test (push) Waiting to run

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.
This commit is contained in:
goon-foss 2026-07-22 09:11:11 +02:00
parent 8e40993c4f
commit 3b225c1d5e
3 changed files with 36 additions and 0 deletions

View file

@ -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';

View file

@ -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',

View file

@ -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<typeof Alert.alert>
) => {
if (AppState.currentState !== 'active') return;
return _origAlert(...args);
}) as typeof Alert.alert;