Repository navigation
Conversation
Sentry builds its relay with BlacklistAdapter, which refuses a GitHub Enterprise or self-managed GitLab host that resolves to an internal address by raising its own RestrictedIPAddress from inside urllib3's connect. That error is neither coded nor a requests exception, so GitServer counted it as unhandled_exception and re-raised it, and Sentry had to catch, report and answer it itself. scm can't import Sentry's exception, so the caller names it in GitRelay(refused_host_errors=...), and the relay raises GitRemoteRefused in its place. GitServer then counts and answers it like its other refusals. The original is dropped with "from None" because its traceback runs through urllib3 frames that hold the Authorization header, and the new error says nothing of the address. The constructor checks the tuple because an except clause with anything else fails only when a request does, as a TypeError chained to that request's error.
A fixed list of refused-host exception types only covers that one case. A map_error callable lets the caller turn any error of its adapter into a coded error, while scm keeps owning the error classes and their status. The relay's own conversions of requests and urllib3 errors, and its own coded errors, still run first, so the mapper never sees an exception that holds the Authorization header and can't relabel the client going away. A mapped error is raised "from None" because a refusal raised as urllib3 connects carries frames that hold the header.
vaind
marked this pull request as ready for review
October 27, 2026 22:53
2 tasks
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.
Sentry's git endpoint (getsentry/sentry#128444) relays git requests through
GitRelaywith Sentry'sBlacklistAdapter, so a GitHub Enterprise or self-managed GitLab host that resolves to an internal address is refused. The adapter refuses by raising Sentry's ownRestrictedIPAddress. scm doesn't know that exception, soGitServercounts the refusal asunhandled_exceptionand re-raises it, and Sentry's view has to catch, report and answer it itself.Approach
GitRelay(map_error=...)takes a function that gets an exception from the upstream request and returns either a coded error to raise in its place orNoneto let the original through unchanged. scm can't import Sentry's exception, so the caller decides which of its adapter's errors mean what. Without a mapper, nothing changes.ResourceGatewayTimeout,ResourceServiceUnavailableand the rest, and the relay's own coded errors (such as the client going away mid-body) pass straight through. So the mapper never sees an exception that holds theAuthorizationheader, and can't relabel those.from None. A refusal raised as urllib3 connects has a traceback that runs through urllib3 frames holding theAuthorizationheader.GitRemoteRefused(git_remote_refused) for a refused host. Its message doesn't name the host or address, like the relay's other errors.GitServeranswers it with a 502, next togit_remote_not_https, the other remote the relay won't connect to. A 503 there means "temporarily unavailable, the request can be retried" (resource_service_unavailable), and retrying a refused host never helps. Sentry answers this case with a 503 today; after the bump it becomes a 502.Usage, for an adapter that refuses with
HostRefused:Tests
A test adapter refuses the way
BlacklistAdapterdoes, from inside urllib3's connect.GitRemoteRefusedwith no cause, a suppressed context, and neither the token nor the address.GitServeranswers it with a 502 and countsgit_remote_refusedrather thanunhandled_exception.None, the original propagates as raised.client_closed_requestnever reach the mapper.Dropping
from None, the_STATUSentry or the pass-through of the relay's own errors, or calling the mapper before the requests handling, each fails a test.After release
featmakes this a minor release. Sentry's bump PR then passesmap_error=lambda e: GitRemoteRefused() if isinstance(e, RestrictedIPAddress) else Noneinmake_git_server()and drops the view's ownexcept RestrictedIPAddressbranch.