fix(base): preserve error metadata through error wrapping

Aperta
#288 0 commenti 0 reazioni 1 assegnatario Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@ffumero2003 ci sta già lavorando.

Dal 3/11/2026.

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

bug

Context

b2err (base/base.go:48) implements Error() but not Unwrap() (base/base.go:56). The public error helpers — base.Action, base.Code, base.MsgCode, base.Backoff, and b2.IsNotExist / b2.IsUpdateConflict — inspect the error with a direct type assertion to the unexported b2err type. Once a b2err is wrapped (for example fmt.Errorf("...: %w", err), which is normal Go practice), those assertions miss and all of the error metadata is lost.

Evidence (probe)
base error direct   status=503 code=service_unavailable action=2 backoff=30s
base error wrapped  status=0   code=""                  action=3 backoff=0s
IsNotExist direct=true  wrapped=false

(action 2 = Retry, 3 = Punt.) A caller that wraps a blazer error can no longer determine the HTTP status, B2 code, retry action, or server delay, and IsNotExist returns a false negative.

Related decision (not blocking this issue)

parseRetryAfterSeconds caps any Retry-After of 30s or more to 30s (base/base.go:192), and Backoff() caps again (base/base.go:238). This is intentional (comment at base/base.go:235), but it means the client can retry sooner than a server explicitly requested. Worth a maintainer decision — honor longer server delays (defer or return the error) versus keep the 30s ceiling — to settle alongside the error-handling work here.

Acceptance criteria

  • R1. b2err implements Unwrap().
  • R2. base.Action, Code, MsgCode, Backoff, and b2.IsNotExist / IsUpdateConflict use chain-aware inspection (errors.As) so metadata survives wrapping.
  • R3. Tests cover wrapped-error cases for each helper.
  • R4. Optional: expose a small public error interface (operation, HTTP status, B2 code, action, server delay) for programmatic handling, modeled on the AWS SDK for Go v2 error-chain design.

In scope

  • Error chaining for b2err and the chain-aware base/b2 helpers listed in the acceptance criteria, plus wrapped-error regression tests.
  • A public error interface remains optional, as stated in the acceptance criteria.

Out of scope

Deferred polish (separate, later — not this issue)

Godoc / b2sim quickstart / stale harness prereq — the prereq is a one-line doc fix (just do it in a passing PR); the rest is minor polish. At most one small "docs" issue later, not three now.

Verification

Run the repository regression checks with live credentials unset:

unset B2_APPLICATION_KEY_ID B2_APPLICATION_KEY B2_ACCOUNT_ID B2_ACCOUNT_KEY
go build ./...
go vet ./...
go test -race -count=1 ./base ./b2/...
  • Wrap the same errors with fmt.Errorf("...: %w", err) and assert each named helper retains the direct error's expected metadata/classification.
  • Demonstrate red for the chain-awareness changes and green after restoration. Keep the optional public interface optional and the deferred polish excluded.
  • Expected result: the checks above succeed and the observable outcomes in Acceptance criteria are demonstrated. If a check cannot run, report Could not run because: ...; if it starts but fails, report Could not complete because: .... A skipped check is not a pass.

Links

  • base/base.go:48-56 (b2err, no Unwrap)
  • Model: AWS SDK for Go v2 error chain
Lingua principale
Go
Stelle
66
Fork
18
Merge medio
1g 10h
PR unite (30g)
132

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di Backblaze/blazer

Tutte le issue di Backblaze/blazer

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.