Repository navigation
fix(cli): Keep timeout guidance and name the real cause of network errors - #1904
Merged
Merged
Conversation
…rors SDK-backed calls wrapped every fetch-layer failure as "Network error ... Check your internet connection", including our own TimeoutError (which already points at status.sentry.io) and raw undici "fetch failed" errors whose real errno sits on `cause`. The wrapper also bypassed the network-error silencing added for CLI-16W, so these all landed in CLI-29S. - Re-throw any CliError from the fetch layer unchanged in unwrapResult. - Name the Sentry URL, the underlying errno, and a matching next step (status page on SaaS, SENTRY_URL check on self-hosted). - Keep the original error on `cause` and silence wrapped "fetch failed". Co-Authored-By: Miguel Betegon <miguel.betegon@sentry.io>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Network error guidance now resolves the Sentry URL the same way request routing does (env, then the stored login's host), so a self-hosted login without SENTRY_URL is no longer told it failed to reach sentry.io. Since unwrapResult now rethrows TimeoutError instead of wrapping it as ApiError(0), `org list` skips an account whose server times out (as it does for other unreachable servers), and alert list failures keep the timeout's class and hint.
The all-targets-failed branch of `issue list` only preserved ApiError and wrapped everything else in a plain Error. Now that unwrapResult rethrows TimeoutError unchanged, rethrow it with the prefix so its status-page hint and timeout exit code survive.
SENTRY_HOST takes precedence over SENTRY_URL, so telling a user with SENTRY_HOST set to change SENTRY_URL pointed them at a no-op.
Checked against real CLI runs:
- Network errors show the innermost cause instead of "fetch failed",
including causes without an errno (e.g. "bad port").
- Self-hosted: say where the URL comes from (SENTRY_HOST, SENTRY_URL, or
the stored login) and how to change it, plus a curl command to test
the connection.
- With HTTPS_PROXY/HTTP_PROXY set, point at the proxy (by variable name,
never its value) instead of the errno hint, which then describes the
proxy connection.
- Timeouts name the operation ("Failed to create release: Request timed
out after 30s."), like ApiError does, and only point self-hosted users
at their own server, not status.sentry.io.
Co-Authored-By: Miguel Betegon <miguel.betegon@sentry.io>
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d3771ca. Configure here.
The API transport calls plain Node fetch, which ignores HTTPS_PROXY and HTTP_PROXY unless NODE_USE_ENV_PROXY is set, and the hint ignored NO_PROXY. Naming a proxy the CLI did not use hid the real errno guidance, so keep the errno-specific next step whatever proxy variables are set.
Follow the CLI's own hint patterns: suggest the `sentry status` command (with --url for self-hosted, which probes /_health/) instead of the status page URL, put the timeout's next step on an indented 'Verb with: command' line like other TimeoutError hints, and build the login hint with getUrlLoginCommand so it names the running program. sentry-mcp has no status command, so it keeps the URL fallbacks. Co-Authored-By: Miguel Betegon <miguel.betegon@sentry.io>
betegon
requested changes
Nov 4, 2026
Hardcode `sentry status` like the CLI's other hints, without per-program fallbacks, and drop the curl suggestion from self-hosted network errors.
betegon
approved these changes
Nov 4, 2026
7 tasks done
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Fixes the messaging and telemetry behind CLI-29S ("Failed to create release: Network error").
unwrapResultre-threw onlyAuthError/ApiErrorfrom the fetch layer.throwApiErrorthen wrapped everything else asNetwork error … Check your internet connection and try again. Three problems came from that:TimeoutErrorlost its guidance. A request timeout already carries a hint that points at Sentry's status, but the wrapper replaced it with "check your internet connection". AnyCliErrorthrown by the fetch layer now passes through unchanged (this also coversHostScopeError).TypeError: fetch failedand puts the errno (ENOTFOUND,ECONNREFUSED, …) oncause, which was never shown. The detail now names the Sentry URL, the errno message, and a next step for that errno. It ends withsentry statuson SaaS, or aSENTRY_URL/SENTRY_HOSTcheck on self-hosted.TypeError, and SDK-backed calls never surface the raw error. The wrapper now keeps the original oncause, andclassifySilencedtreats a wrappedfetch failedasnetwork_error. TLS errors (ApiError(0)without that cause) and non-network causes, such as a local SQLiteunable to open database file, stay captured.A review question: silencing means
ECONNRESET-style failures against sentry.io show up only in the silenced-error metric, not as issues. Timeouts stay captured asTimeoutError.Before / after
Real
sentry release createruns from source, on the base commit and on this branch. For the demo the request timeout was cut to 2s (it is 30s), and the sentry.io case was simulated by routing through a local port that never answers.[exit N]is the exit code.Before: every case printed the same thing. Connection failures showed
Cause: fetch failed. Timeouts showedCause: Request timed out after 2s., with the same "check your internet connection" advice and exit code 30.After: each message names the server, the real cause, and the next step that fits it, in the CLI's existing error formats:
Network errortitle (so grouping is unchanged) and use theApiErrordetail layout from the 401/403 enrichment: an indented detail, a blank line, then one step per line, with commands asVerb with: <command>.TimeoutError's layout and exit code (31): a sentence, then an indented action line, like theView in Sentry:/Or retry:lines in theissue explainandissue plantimeout hints.sentry statuscommand. For a self-hosted timeout it'ssentry status --url <server>, which probes/_health/. The login hint usesgetUrlLoginCommand(), like the other login hints.Self-hosted, hostname doesn't resolve:
Self-hosted, server not running:
Self-hosted, server accepts the connection but never answers:
sentry.io never answers:
The CLI's API requests use plain Node
fetch, which ignoresHTTPS_PROXY/HTTP_PROXYunlessNODE_USE_ENV_PROXYis set. So these messages don't name a proxy, and a proxy variable never replaces the hint for the actual error.via bete.
--
View Session [Sentry]