…failures
MAILSPRING-CLIENT-Q: When mailsync crashes with an uncaught C++ exception
(e.g. a libcurl/TLS failure while refreshing an OAuth token) instead of
exiting cleanly, MailsyncProcess._spawnAndWait's close handler only read
the numeric `code` param, so a signal-terminated process rendered as an
uninformative "mailsync: null" error with no indication of what happened.
Nearly all 121 occurrences (35 users, mostly mainland China) show the same
underlying signature: mailsync logs `"offline":true,"retryable":true` before
crashing while calling login.microsoftonline.com during account setup -
consistent with local network/TLS interception rather than an app bug.
Capture the `signal` param so future crashes are diagnosable, and detect
the "offline" marker to surface a friendly, localized connection error
tagged with `isNetworkError`. oauth-signin-page.tsx already skips Sentry
reporting for fetch-based network errors; extend that check to include
mailsync-originated network failures too.
Claude-Session: https://claude.ai/code/session_01Ndr7sjz8nxt9VhvGb7DueH
Fixes MAILSPRING-CLIENT-Q
What I observed
Sentry issue MAILSPRING-CLIENT-Q ("An unknown error has occurred mailsync: null.") had 121 occurrences across 35 users over 30 days. Sampling ~15 individual events showed:
MailsyncProcess._spawnAndWait'sclosehandler inapp/src/mailsync-process.ts, triggered from the OAuth onboarding flow (onboarding-helpers.ts→finalizeAndValidateAccount→proc.test()).MakeOAuthRefreshRequest→PerformRequest→ValidateRequestResp(CURLcode, ...).login.microsoftonline.com, not an app bug.closeevent fires withcode === nulland no JSON response._spawnAndWait's handler only read thecodeparam (ignoringsignal), so the resulting error was a useless"An unknown error has occurred mailsync: null. <raw crash log>"— no signal info, and a wall of C++ stack trace text as the "message".oauth-signin-page.tsx's_onErroralready has a precedent for skipping Sentry on expected network errors (err.message.includes('Failed to fetch')) and user-config errors (err.isUserError), but had no way to recognize this mailsync-originated network failure, so it reported it every time.The fix
app/src/mailsync-process.ts:_spawnAndWait'scloselistener now capturessignalin addition tocode, so any future non-network crash includes the signal in its message instead of a barenull._buildCrashError(code, signal, rawLog): detects the"offline":truemarker mailsync logs for this class of exception and, when present, builds a friendly, localizedErrorConnectionmessage tagged witherror.isNetworkError = trueinstead of dumping the raw crash log as the error message.app/internal_packages/onboarding/lib/oauth-signin-page.tsx:_onErrornow also treatserr.isNetworkErroras a network error (skipsAppEnv.reportError, same as the existingFailed to fetchcase), and shows the friendlier "check your internet connection" message to the user instead of the raw crash dump.This doesn't fix the underlying TLS/network condition (that's outside the app's control), but it stops non-actionable, expected connectivity failures from generating Sentry noise, and makes any real future crash in this path show the signal that killed the process instead of
null.Test plan
npx tsc --noEmitpasses for the changed files.proc.test()rejects for other reasons (e.g. bad credentials), sinceLocalizedErrorStrings.ErrorConnectionand the JSON-response error path are unchanged for those cases.Generated by Claude Code