diff --git a/packages/core/ui/frame/frame-helper-for-android.ts b/packages/core/ui/frame/frame-helper-for-android.ts index d50236d4e7..63281c0ae0 100644 --- a/packages/core/ui/frame/frame-helper-for-android.ts +++ b/packages/core/ui/frame/frame-helper-for-android.ts @@ -112,21 +112,33 @@ 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. + if (Trace.isEnabled()) { + Trace.write(`${fragment}.onCreateView: entry is null or undefined`, Trace.categories.NativeLifecycle, Trace.messageType.warn); + } 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. + if (Trace.isEnabled()) { + Trace.write(`${fragment}.onCreateView: entry has no resolvedPage`, Trace.categories.NativeLifecycle, Trace.messageType.warn); + } 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. + if (Trace.isEnabled()) { + Trace.write(`${fragment}.onCreateView: this.frame is null or undefined`, Trace.categories.NativeLifecycle, Trace.messageType.warn); + } return null; }