Agent Skills by ALSEL
Anthropic Claudeその他⭐ リポ 0品質スコア 50/100

golang-samber-oops

`samber/oops`を使ったGoの構造化エラーハンドリングを支援するスキルで、エラービルダー・スタックトレース・エラーコード・コンテキスト付与・エラーラップ・属性管理・ユーザー向けとデバッグ向けのメッセージ分離・パニックリカバリー・ロガー連携に対応します。`samber/oops`を新規導入する場合や、すでに`github.com/samber/oops`をインポートしているコードベースで作業する際に適用されます。

description の原文を見る

Structured error handling in Golang with samber/oops — error builders, stack traces, error codes, error context, error wrapping, error attributes, user-facing vs developer messages, panic recovery, and logger integration. Apply when using or adopting samber/oops, or when the codebase already imports github.com/samber/oops.

SKILL.md 本文

ペルソナ: あなたはエラーを構造化データとして扱う Go エンジニアです。すべてのエラーは十分なコンテキスト(ドメイン、属性、トレース)を含み、オンコール対応者が開発者に質問することなく問題を診断できます。

samber/oops 構造化エラーハンドリング

samber/oops は Go の標準的なエラーハンドリングのドロップイン置き換えです。構造化コンテキスト、スタックトレース、エラーコード、パブリックメッセージ、パニック復旧を追加します。変数データは .With() 属性(メッセージ文字列ではなく)に格納されるため、APM ツール(Datadog、Loki、Sentry)はエラーを適切にグループ化できます。標準ライブラリのアプローチ(ログサイトで slog 属性を追加する)とは異なり、oops 属性はコールスタック全体を通じてエラーと共に移動します。

samber/oops を使用する理由

標準的な Go エラーはコンテキストを欠いています。connection failed は表示されますが、どのユーザーがトリガーしたのか、どのクエリが実行中だったのか、完全なコールスタックは表示されません。samber/oops は以下を提供します:

  • 構造化コンテキスト — あらゆるエラー上のキー値属性
  • スタックトレース — 自動的なコールスタック取得
  • エラーコード — マシンリーダブルな識別子
  • パブリックメッセージ — 技術的詳細とは別のユーザーセーフなメッセージ
  • 低カーディナリティメッセージ — メッセージ文字列ではなく .With() 属性に変数データを格納し、APM ツールがエラーを適切にグループ化できるようにします

このスキルは網羅的ではありません。詳細な情報についてはライブラリドキュメントとコード例を参照してください。Context7 はディスカバリープラットフォームとして支援できます。

コアパターン:エラービルダーチェーン

すべての oops エラーは流暢なビルダーパターンを使用します:

err := oops.
    In("user-service").           // domain/feature
    Tags("database", "postgres").  // categorization
    Code("network_failure").       // machine-readable identifier
    User("user-123", "email", "foo@bar.com").  // user context
    With("query", query).          // custom attributes
    Errorf("failed to fetch user: %s", "timeout")

終端メソッド:

  • .Errorf(format, args...) — 新しいエラーを作成
  • .Wrap(err) — 既存のエラーをラップ
  • .Wrapf(err, format, args...) — メッセージを含めてラップ
  • .Join(err1, err2, ...) — 複数のエラーを結合
  • .Recover(fn) / .Recoverf(fn, format, args...) — パニックをエラーに変換

エラービルダーメソッド

メソッドユースケース
.With("key", value)カスタムキー値属性を追加(遅延 func() any 値対応)
.WithContext(ctx, "key1", "key2")Go context から属性値を抽出(遅延値対応)
.In("domain")フィーチャー/サービス/ドメインを設定
.Tags("auth", "sql")カテゴリタグを追加(err.HasTag("tag") でクエリ可能)
.Code("iam_authz_missing_permission")マシンリーダブルエラー識別子/スラッグを設定
.Public("Could not fetch user.")ユーザーセーフメッセージを設定(技術的詳細と分離)
.Hint("Runbook: https://doc.acme.org/doc/abcd.md")開発者向けのデバッグヒントを追加
.Owner("team/slack")責任を持つチーム/オーナーを特定
.User(id, "k", "v")ユーザー識別子と属性を追加
.Tenant(id, "k", "v")テナント/組織コンテキストと属性を追加
.Trace(id)トレース/相関 ID を追加(デフォルト:ULID)
.Span(id)作業単位/操作を表すスパン ID を追加(デフォルト:ULID)
.Time(t)エラータイムスタンプをオーバーライド(デフォルト:time.Now()
.Since(t)t 以降の経過時間に基づいて期間を設定(err.Duration() で公開)
.Duration(d)明示的なエラー期間を設定
.Request(req, includeBody)*http.Request をアタッチ(オプションでボディを含む)
.Response(res, includeBody)*http.Response をアタッチ(オプションでボディを含む)
oops.FromContext(ctx)Go context に保存された OopsErrorBuilder から開始

一般的なシナリオ

データベース/リポジトリレイヤー

func (r *UserRepository) FetchUser(id string) (*User, error) {
    query := "SELECT * FROM users WHERE id = $1"
    row, err := r.db.Query(query, id)
    if err != nil {
        return nil, oops.
            In("user-repository").
            Tags("database", "postgres").
            With("query", query).
            With("user_id", id).
            Wrapf(err, "failed to fetch user from database")
    }
    // ...
}

HTTP ハンドラレイヤー

func (h *Handler) CreateUser(w http.ResponseWriter, r *http.Request) {
    userID := getUserID(r)

    err := h.service.CreateUser(r.Context(), userID)
    if err != nil {
        return oops.
            In("http-handler").
            Tags("endpoint", "/users").
            Request(r, false).
            User(userID).
            Wrapf(err, "create user failed")
    }

    w.WriteHeader(http.StatusCreated)
}

再利用可能なビルダーを使用したサービスレイヤー

func (s *UserService) CreateOrder(ctx context.Context, req CreateOrderRequest) error {
    builder := oops.
        In("order-service").
        Tags("orders", "checkout").
        Tenant(req.TenantID, "plan", req.Plan).
        User(req.UserID, "email", req.UserEmail)

    product, err := s.catalog.GetProduct(ctx, req.ProductID)
    if err != nil {
        return builder.
            With("product_id", req.ProductID).
            Wrapf(err, "product lookup failed")
    }

    if product.Stock < req.Quantity {
        return builder.
            Code("insufficient_stock").
            Public("Not enough items in stock.").
            With("requested", req.Quantity).
            With("available", product.Stock).
            Errorf("insufficient stock for product %s", req.ProductID)
    }

    return nil
}

エラーラップのベストプラクティス

する:直接ラップ、nil チェック不要

// ✓ 良い — Wrap は err が nil の場合 nil を返す
return oops.Wrapf(err, "operation failed")

// ✗ 悪い — 不必要な nil チェック
if err != nil {
    return oops.Wrapf(err, "operation failed")
}
return nil

する:各レイヤーでコンテキストを追加

各アーキテクチャレイヤーは Wrap/Wrapf を経由してコンテキストを追加すべきです。パッケージ境界ごとに少なくとも 1 回(すべての関数呼び出しごとではなく)。

// ✓ 良い — 各レイヤーが関連するコンテキストを追加
func Controller() error {
    return oops.In("controller").Trace(traceID).Wrapf(Service(), "user request failed")
}

func Service() error {
    return oops.In("service").With("op", "create_user").Wrapf(Repository(), "db operation failed")
}

func Repository() error {
    return oops.In("repository").Tags("database", "postgres").Errorf("connection timeout")
}

する:エラーメッセージを低カーディナリティに保つ

エラーメッセージは APM 集計のために低カーディナリティである必要があります。メッセージに変数データを補間するとDatadog、Loki、Sentry でのグループ化が破壊されます。

// ✗ 悪い — 高カーディナリティ、APM グループ化を破壊
oops.Errorf("failed to process user %s in tenant %s", userID, tenantID)

// ✓ 良い — 静的メッセージ + 構造化属性
oops.With("user_id", userID).With("tenant_id", tenantID).Errorf("failed to process user")

パニック復旧

oops.Recover() はゴルーチン境界で使用する必要があります。パニックを構造化エラーに変換します:

func ProcessData(data string) (err error) {
    return oops.
        In("data-processor").
        Code("panic_recovered").
        Hint("Check input data format and dependencies").
        With("panic_value", r).
        Recover(func() {
            riskyOperation(data)
        })
}

エラー情報へのアクセス

samber/oops エラーは標準の error インターフェイスを実装します。追加情報にアクセスします:

if oopsErr, ok := err.(oops.OopsError); ok {
    fmt.Println("Code:", oopsErr.Code())
    fmt.Println("Domain:", oopsErr.Domain())
    fmt.Println("Tags:", oopsErr.Tags())
    fmt.Println("Context:", oopsErr.Context())
    fmt.Println("Stacktrace:", oopsErr.Stacktrace())
}

// パブリックメッセージをフォールバック付きで取得
publicMsg := oops.GetPublic(err, "Something went wrong")

出力フォーマット

fmt.Printf("%+v\n", err)       // verbose with stack trace
bytes, _ := json.Marshal(err)  // JSON for logging
slog.Error(err.Error(), slog.Any("error", err))  // slog integration

コンテキスト伝播

Go context を通じてエラーコンテキストを伝達します:

func middleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        builder := oops.
            In("http").
            Request(r, false).
            Trace(r.Header.Get("X-Trace-ID"))

        ctx := oops.WithBuilder(r.Context(), builder)
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}

func handler(ctx context.Context) error {
    return oops.FromContext(ctx).Tags("handler", "users").Errorf("something failed")
}

アサーション、構成、追加ロガー例については、Advanced patterns を参照してください。

参考資料

クロスリファレンス

  • → 一般的なエラーハンドリングパターンについては samber/cc-skills-golang@golang-error-handling スキルを参照
  • → ロガー統合と構造化ログについては samber/cc-skills-golang@golang-observability スキルを参照

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
samber
リポジトリ
samber/cc-skills-golang
ライセンス
MIT
最終更新
不明

Source: https://github.com/samber/cc-skills-golang / ライセンス: MIT

関連スキル

汎用その他⭐ リポ 1,982

superfluid

Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper

by LeoYeAI
汎用その他⭐ リポ 100

civ-finish-quotes

実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。

by huxiuhan
汎用その他⭐ リポ 1,110

nookplot

Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。

by BankrBot
汎用その他⭐ リポ 59

web3-polymarket

Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。

by elophanto
汎用その他⭐ リポ 52

ethskills

Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。

by jiayaoqijia
汎用その他⭐ リポ 44

xxyy-trade

このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。

by Jimmy-Holiday
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: samber · samber/cc-skills-golang · ライセンス: MIT