wrapcheck は外部パッケージから返されたエラーがラップされているかをチェックするツールです。
解決する問題
外部パッケージのエラーをそのまま返すと、エラーの発生箇所を特定できなくなります。fmt.Errorf("...: %w", err) でラップすることでコンテキストが付与され、デバッグ時にエラーの伝播経路を追跡できます。
1 2 3 4 5 6 7 8
| func GetUser(ctx context.Context, id string) (*User, error) { user, err := db.FindByID(ctx, id) if err != nil { return nil, err } return user, nil }
|
1 2 3 4 5 6 7 8
| func GetUser(ctx context.Context, id string) (*User, error) { user, err := db.FindByID(ctx, id) if err != nil { return nil, fmt.Errorf("find user %s: %w", id, err) } return user, nil }
|
設定
公式ドキュメント
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| version: "2"
linters: enable: - wrapcheck settings: wrapcheck: ignore-sigs: - .Errorf( - errors.New( - errors.Unwrap( - errors.Join( - .Wrap( - .Wrapf( - .WithMessage( - .WithMessagef( - .WithStack( ignore-package-globs: - encoding/* - github.com/pkg/errors
|
オプション
| オプション |
型 |
デフォルト |
説明 |
ignore-sigs |
[]string |
[.Errorf(, errors.New(, errors.Unwrap(, errors.Join(, .Wrap(, .Wrapf(, .WithMessage(, .WithMessagef(, .WithStack(] |
この文字列を含む関数シグネチャから返されたエラーを無視する |
ignore-sig-regexps |
[]string |
[] |
正規表現でマッチする関数シグネチャを無視する |
ignore-package-globs |
[]string |
[] |
エラーを返すパッケージの glob パターンで無視する |
ignore-interface-regexps |
[]string |
[] |
指定したインターフェースのメソッドから返されたエラーを無視する |
report-internal-errors |
bool |
false |
同一パッケージ内のエラーもチェック対象にする |
サンプル
検出例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import "github.com/redis/go-redis/v9"
func GetCache(ctx context.Context, key string) (string, error) { val, err := rdb.Get(ctx, key).Result() if err != nil { return "", err } return val, nil }
func ReadConfig(r io.Reader) ([]byte, error) { data, err := io.ReadAll(r) if err != nil { return nil, err } return data, nil }
|
修正例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| func GetCache(ctx context.Context, key string) (string, error) { val, err := rdb.Get(ctx, key).Result() if err != nil { return "", fmt.Errorf("get cache %s: %w", key, err) } return val, nil }
func ReadConfig(r io.Reader) ([]byte, error) { data, err := io.ReadAll(r) if err != nil { return nil, fmt.Errorf("read config: %w", err) } return data, nil }
|
注意点
- デフォルトでは同一パッケージ内のエラーはチェック対象外。
report-internal-errors: true で有効化できる
fmt.Errorf、errors.New、errors.Join などのエラー生成関数はデフォルトで除外されている
encoding/json などのエラーをそのまま返したいケースでは ignore-package-globs で除外する
- errorlint と併用すると、エラーのラップと比較の両方を包括的にチェックできる
参考リンク