fix(base): preserve error metadata through error wrapping

オープン
#288 コメント 0 件 リアクション 0 件 担当者 1 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@ffumero2003 がすでに取り組んでいます。

2026年11月3日 から。

評価

この issue はまだ評価されていません。

説明

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
主要言語
Go
スター
66
フォーク
18
平均マージ
1日 10時間
マージ済み PR(30日)
132

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

Backblaze/blazer のほかの issue

Backblaze/blazer の issue をすべて見る

似ている issue

Go の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。