Skip to content

Stop unhandled rejection from Android logcat subprocess on teardown#162

Merged
V3RON merged 1 commit into
mainfrom
fix/logcat-subprocess-teardown-race
Jul 14, 2026
Merged

Stop unhandled rejection from Android logcat subprocess on teardown#162
V3RON merged 1 commit into
mainfrom
fix/logcat-subprocess-teardown-race

Conversation

@V3RON

@V3RON V3RON commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

What is this?

Fixes a crash in the Android E2E CI job where Harness shutdown could throw an unhandled SubprocessError from the adb logcat process (Command failed with exit code 255: adb ... logcat -v threadtime -b crash ...), killing the whole test process even though the app session's own teardown code already wraps that stream in a try/catch.

How does it work?

The Android app session's logcat stream pipes both stdout and stderr, and nano-spawn merges them into a single iterable using an internal Promise.race. Killing the underlying process directly (childProcess.kill()) could make both the stdout and stderr sides observe the process death and reject at nearly the same time; only the "winning" rejection was ever seen by the surrounding try/catch, leaving the other one unhandled.

Two changes fix this:

  • The logcat subprocess is now cancelled via an AbortController/AbortSignal passed into nano-spawn's own signal option, which is its supported cancellation path, instead of killing the child process handle directly.
  • Harness shutdown now waits for the app session (and its logcat stream) to fully dispose before disposing the platform instance, instead of racing the two. Previously they ran in the same Promise.all, so the emulator could be torn down while adb logcat was still attached to it, which is what produced the adb-side exit code 255 in the first place.

Why is this useful?

The Android E2E and crash-validation CI jobs no longer intermittently fail with an unrelated, misleading SubprocessError during normal shutdown.

Killing the adb logcat child process directly could make nano-spawn's
merged stdout/stderr iterators both reject at once; only one rejection
was ever observed by the try/catch around the for-await loop, leaving
the other unhandled and crashing the whole E2E job. Use nano-spawn's
own AbortSignal-based cancellation instead, and stop racing app-session
teardown against emulator shutdown so the device's log stream is fully
closed before the device itself goes away.
@vercel

vercel Bot commented Jul 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
react-native-harness Ready Ready Preview, Comment Jul 14, 2026 11:46am

Request Review

@V3RON V3RON changed the title fix: stop unhandled rejection from Android logcat subprocess on teardown Stop unhandled rejection from Android logcat subprocess on teardown Jul 14, 2026
@V3RON V3RON merged commit 4fee716 into main Jul 14, 2026
11 checks passed
@V3RON V3RON deleted the fix/logcat-subprocess-teardown-race branch July 14, 2026 12:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant