MCP HubMCP Hub
SKILL·345695

go-error-handling

eduardo-sl
更新日 27 days ago
4 閲覧
70
9
70
GitHubで表示
テストaitestingapidesign

について

このスキルは、Go言語における慣用的なエラー処理のガイダンスを提供し、エラーのラッピング、センチネルエラー、カスタムタイプ、およびerrorsパッケージについて網羅しています。開発者が適切なエラー処理を実装し、エラータイプを設計し、実戦で検証されたパターンを用いてエラー連鎖をデバッグすることを支援します。errors.Isやerrors.Asを扱う際や、エラー処理コードをレビューする際にご活用ください。

クイックインストール

Claude Code

推奨
メイン
npx skills add eduardo-sl/go-agent-skills -a claude-code
プラグインコマンド代替
/plugin add https://github.com/eduardo-sl/go-agent-skills
Git クローン代替
git clone https://github.com/eduardo-sl/go-agent-skills.git ~/.claude/skills/go-error-handling

このコマンドをClaude Codeにコピー&ペーストしてスキルをインストールします

ドキュメント

Go Error Handling

Go's explicit error handling is a feature, not a limitation. These patterns ensure errors are informative, actionable, and properly propagated.

1. Error Decision Tree

When creating or returning an error, follow this tree:

  1. Simple, no extra context needed?errors.New("message")
  2. Need to add context to existing error?fmt.Errorf("doing X: %w", err)
  3. Caller needs to detect this error? → Sentinel var or custom type
  4. Error carries structured data? → Custom type implementing error
  5. Propagating from downstream? → Wrap with %w and add context

2. Sentinel Errors

Use package-level var for errors that callers need to check:

// ✅ Good — exported sentinel error
var (
    ErrNotFound     = errors.New("user: not found")
    ErrUnauthorized = errors.New("user: unauthorized")
)

// Naming convention: Err + Description
// Prefix with package context in the message

Callers check with errors.Is:

if errors.Is(err, user.ErrNotFound) {
    // handle not found
}

NEVER compare errors with ==. Always use errors.Is().

3. Custom Error Types

When errors need to carry structured information:

type ValidationError struct {
    Field   string
    Message string
}

func (e *ValidationError) Error() string {
    return fmt.Sprintf("validation: field %s: %s", e.Field, e.Message)
}

// Callers extract with errors.As:
var valErr *ValidationError
if errors.As(err, &valErr) {
    log.Printf("invalid field: %s", valErr.Field)
}

4. Error Wrapping

ALWAYS add context when propagating errors up the stack. Use %w to preserve the error chain:

// ✅ Good — context added, chain preserved
func getUser(id int64) (*User, error) {
    row, err := db.QueryRow(ctx, query, id)
    if err != nil {
        return nil, fmt.Errorf("get user %d: %w", id, err)
    }
    // ...
}

// ❌ Bad — no context
return nil, err

// ❌ Bad — chain broken, callers can't errors.Is/As
return nil, fmt.Errorf("failed: %v", err)

When NOT to use %w

Use %v instead of %w when you explicitly want to break the error chain, preventing callers from depending on internal implementation errors:

// Intentionally hiding internal DB error from public API
return nil, fmt.Errorf("user lookup failed: %v", err)

5. Handle Errors Exactly Once

An error should be either logged OR returned, never both:

// ✅ Good — return the error, let caller decide
func loadConfig(path string) (*Config, error) {
    data, err := os.ReadFile(path)
    if err != nil {
        return nil, fmt.Errorf("load config %s: %w", path, err)
    }
    // ...
}

// ❌ Bad — log AND return (error handled twice)
func loadConfig(path string) (*Config, error) {
    data, err := os.ReadFile(path)
    if err != nil {
        log.Printf("failed to read config: %v", err) // handled once
        return nil, err                                 // handled again
    }
    // ...
}

The rule: the component that decides what to do about the error is the one that logs/metrics it. Everyone else wraps and returns.

6. Error Naming Conventions

// Sentinel errors: Err prefix
var ErrNotFound = errors.New("not found")

// Error types: Error suffix
type NotFoundError struct { ... }
type ValidationError struct { ... }

// Error messages: lowercase, no punctuation, no "failed to" prefix
// Include context: "package: action: detail"
errors.New("auth: token expired")
fmt.Errorf("user: get by id %d: %w", id, err)

7. Panic Rules

Panic is NOT error handling. Use panic only when:

  • Program initialization fails and cannot continue (template.Must, flag parsing)
  • Programmer error that should never happen (violated invariant)
  • Nil dereference that indicates a bug, not a runtime condition

In tests, use t.Fatal / t.FailNow, never panic.

In HTTP handlers and middleware, recover from panics at the boundary to prevent one request from crashing the server.

8. Error Checking Patterns

// Inline error check — preferred for simple cases
if err := doSomething(); err != nil {
    return fmt.Errorf("do something: %w", err)
}

// Multi-return with named result — acceptable for complex functions
func process() (result string, err error) {
    defer func() {
        if err != nil {
            err = fmt.Errorf("process: %w", err)
        }
    }()
    // ...
}

// errors.Join for multiple errors (Go 1.20+)
var errs []error
for _, item := range items {
    if err := validate(item); err != nil {
        errs = append(errs, err)
    }
}
return errors.Join(errs...)

Executable Verification

After writing or reviewing error handling, run the linters that prove the rules above (skip any that is not installed and note it):

go vet ./...                                  # includes printf %w misuse
golangci-lint run --enable errcheck,errorlint # unchecked errors, %v-vs-%w,
                                              # == comparisons on errors

Verification Checklist

  1. No _ discarding errors (unless explicitly justified with comment)
  2. Every fmt.Errorf wrapping uses %w (or %v with documented reason)
  3. Sentinel errors use var Err... naming
  4. Custom error types implement error interface
  5. Callers use errors.Is / errors.As, never == or type assertion
  6. No log-and-return patterns
  7. Error messages are lowercase, contextual, chain-friendly

GitHub リポジトリ

eduardo-sl/go-agent-skills
パス: skills/(code-quality)/go-error-handling
0
FAQ

よくある質問

go-error-handling Skillとは何ですか?

go-error-handling はeduardo-sl が作成した Claude Skillです。Skillは、Claudeが必要に応じて読み込む指示とリソースをまとめ、追加の指示なしで go-error-handling に関連するタスクを実行できるようにします。

go-error-handling をインストールするには?

このページのインストールコマンドを使用してください。go-error-handling をプラグインとして Claude Code に追加するか、リポジトリを skills ディレクトリにクローンし、Claudeを再起動してSkillを読み込みます。

go-error-handling はどのカテゴリに属しますか?

go-error-handling は テスト カテゴリに属します。

go-error-handling は無料で利用できますか?

はい。go-error-handling は AIMCP に掲載されており、無料でインストールできます。

関連スキル

evaluating-llms-harness
テスト

このClaudeスキルは、lm-evaluation-harnessを実行し、MMLUやGSM8Kなど60以上の標準化学術タスクでLLMをベンチマークします。開発者がモデルの品質を比較し、トレーニングの進捗を追跡し、学術的な結果を報告するために設計されています。このツールはHuggingFaceやvLLMモデルを含む様々なバックエンドをサポートしています。

スキルを見る
cloudflare-cron-triggers
テスト

このスキルは、cron式を使用してWorkersをスケジュールするためのCloudflare Cron Triggersの実装に関する包括的な知識を提供します。定期的なタスクの設定、メンテナンスジョブ、自動化されたワークフローの構築を網羅し、無効なcron式やタイムゾーン問題といった一般的な課題への対処法も含みます。開発者はこれを使用して、スケジュールされたハンドラーの設定、cronトリガーのテスト、WorkflowsやGreen Computeとの連携を構成できます。

スキルを見る
webapp-testing
テスト

このClaude Skillは、Playwrightベースのツールキットを提供し、Pythonスクリプトを通じてローカルWebアプリケーションのテストを可能にします。フロントエンドの検証、UIデバッグ、スクリーンショット撮影、ログ表示を実現し、サーバーライフサイクルを管理します。ブラウザ自動化タスクにご利用いただけますが、コンテキストの汚染を避けるため、スクリプトのソースコードを読むのではなく直接実行してください。

スキルを見る
finishing-a-development-branch
テスト

このスキルは、開発者がテストの合格を確認し、構造化された統合オプションを提示することで、完成した作業を仕上げることを支援します。実装が完了した後のマージ、PR作成、ブランチの整理といったワークフローを案内します。コードが準備できてテスト済みの際に使用し、開発プロセスを体系的に完了させましょう。

スキルを見る