Skip to content

Guard nil Sentry hub in fail() and fix EOF recovery order#36

Open
ffittschen wants to merge 1 commit into
cirruslabs:mainfrom
ffittschen:fix/azureblob-nil-hub-panic
Open

Guard nil Sentry hub in fail() and fix EOF recovery order#36
ffittschen wants to merge 1 commit into
cirruslabs:mainfrom
ffittschen:fix/azureblob-nil-hub-panic

Conversation

@ffittschen

Copy link
Copy Markdown

This PR fixes a nil-pointer panic on the azureblob path and a dead recovery branch that together turn a transient error — or any serve error when Sentry is not configured — into a client-visible "socket hang up".

The root cause is fail(), the shared error helper for every azureblob path (the GET download proxy, HEAD, and the PUT/block/multipart save path). It dereferences the Sentry hub unconditionally: sentry.GetHubFromContext returns nil when Sentry is not initialized, so any serve error panics the handler goroutine and net/http closes the connection mid-response. This PR guards the hub so reporting is skipped when none is configured, which fixes the panic across all of those paths at once.

A second defect compounds it: in proxyCacheEntryDownload the io.ErrUnexpectedEOF Range-retry recovery runs after fail(), so it is dead code (fail() panics first). This PR reorders recovery before fail() so a recoverable mid-stream close is retried instead of turned into a hard failure.

Fixes #34.

How to test

  • Assert that go build ./... and go vet ./internal/protocols/azureblob/ are clean.
  • Assert that go test ./internal/protocols/azureblob/... passes, including the new TestFailWithoutSentryHubDoesNotPanic — it panics against the pre-fix fail() and passes on the fix.
  • The full go test ./... suite requires Docker/LocalStack (testcontainers) and was not run in my environment; the offline azureblob unit tests pass.

fail() is the shared error helper for every azureblob path (GET
download, HEAD, and the PUT/block/multipart save path), so both
defects below reach all of them, not only the download that first
surfaced them. Together they turn a transient mid-stream S3 read
interruption — or any serve error when Sentry is not configured — into
a hard, unrecoverable "socket hang up" on the client:

- fail() dereferenced the Sentry hub from the request context
  unconditionally. sentry.GetHubFromContext returns nil when Sentry is
  not initialized, so any serve error panicked the handler goroutine;
  net/http then closed the connection mid-response. Guard the hub so
  reporting is skipped when none is configured.

- The io.ErrUnexpectedEOF Range-retry recovery in
  proxyCacheEntryDownload ran *after* fail(), so it was never reached
  (fail panicked first). Reorder so a recoverable early close is
  retried, and only fail when recovery is inapplicable or fails.

Add a regression test asserting fail() does not panic and still writes
the error response when no Sentry hub is attached to the request.
@ffittschen
ffittschen marked this pull request as ready for review July 7, 2026 12:47
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.

azureblob: fail() panics on a nil Sentry hub when Sentry is not configured

1 participant