diff --git a/packages/core/ui/frame/frame-helper-for-android.ts b/packages/core/ui/frame/frame-helper-for-android.ts index d50236d4e7..093dac0163 100644 --- a/packages/core/ui/frame/frame-helper-for-android.ts +++ b/packages/core/ui/frame/frame-helper-for-android.ts @@ -112,21 +112,30 @@ export class FragmentCallbacksImplementation implements AndroidFragmentCallbacks const entry = this.entry; if (!entry) { - Trace.error(`${fragment}.onCreateView: entry is null or undefined`); + // Recoverable race: a stale fragment is being driven to onCreateView by the + // FragmentManager after its entry was cleared. + // Using Trace.error (routes to an error handler, which throws) would be fatal as the error handler rethrows across the JNI boundary. + // Trace.write(..., Trace.messageType.error) logs without routing through that throwing path. + Trace.write(`${fragment}.onCreateView: entry is null or undefined`, Trace.categories.NativeLifecycle, Trace.messageType.error); return null; } const page = entry.resolvedPage; if (!page) { - Trace.error(`${fragment}.onCreateView: entry has no resolvedPage`); + // Logging via Trace.error (routes to an error handler, which throws) here is fatal because the registered error handler rethrows across the JNI boundary. + // Trace.write(..., Trace.messageType.error) keeps this recoverable path non-fatal. + Trace.write(`${fragment}.onCreateView: entry has no resolvedPage`, Trace.categories.NativeLifecycle, Trace.messageType.error); return null; } const frame = this.frame; if (!frame) { - Trace.error(`${fragment}.onCreateView: this.frame is null or undefined`); + // Recoverable race: the owning frame was already torn down. Returning null discards + // this fragment; using Trace.error (routes to an error handler, which throws) would be fatal as the error handler rethrows across the JNI boundary. + // Trace.write(..., Trace.messageType.error) logs without invoking the throwing error handler. + Trace.write(`${fragment}.onCreateView: this.frame is null or undefined`, Trace.categories.NativeLifecycle, Trace.messageType.error); return null; }