fix(base): preserve error metadata through error wrapping

Abierto
#288 0 comentarios 0 reacciones 1 asignado Ver en GitHub

Los mantenedores suelen responder en 1 día

@ffumero2003 ya está trabajando en esto.

Desde el 3/11/2026.

Evaluación

Este issue todavía no se ha evaluado.

Descripción

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
Lenguaje dominante
Go
Estrellas
66
Forks
18
Merge medio
1 d 10 h
PR fusionados (30 d)
132

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de Backblaze/blazer

Todos los issues de Backblaze/blazer

Issues similares

Más issues de Go

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.