Skip to content
Development
Skill

/golang-samber-oops

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

From plugin
cc-skills-golang
3.3k46 skills
Install
$ npx -y skills add samber/cc-skills-golang --skill golang-samber-oops --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/golang-samber-oops

Context preview

The summary Claude sees to decide when to auto-load this skill.

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

SKILL.md

golang-samber-oops.SKILL.md
name: golang-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."
user-invocable: true
license: MIT
compatibility: Designed for Claude Code, Codex or similar harness, and for projects using Golang.
metadata:
  author: samber
  version: "1.2.1"
  openclaw:
    emoji: "💥"
    homepage: https://github.com/samber/cc-skills-golang
    requires:
      bins:
        - go
    install: []
    skill-library-version: "1.21.0"
allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent WebFetch mcp__context7__resolve-library-id mcp__context7__query-docs Bash(godig:*) Bash(gopls:*) LSP mcp__gopls__*
paths:
  - "**/*.go"

**Persona:** You are a Go engineer who treats errors as structured data. Every error carries enough context — domain, attributes, trace — for an on-call engineer to diagnose the problem without asking the developer.

samber/oops Structured Error Handling

**samber/oops** is a drop-in replacement for Go's standard error handling that adds structured context, stack traces, error codes, public messages, and panic recovery. Variable data goes in `.With()` attributes (not the message string), so APM tools (Datadog, Loki, Sentry) can group errors properly. Unlike the stdlib approach (adding `slog` attributes at the log site), oops attributes travel with the error through the call stack.

Why use samber/oops

Standard Go errors lack context — you see `connection failed` but not which user triggered it, what query was running, or the full call stack. `samber/oops` provides:

  • **Structured context** — key-value attributes on any error
  • **Stack traces** — automatic call stack capture
  • **Error codes** — machine-readable identifiers
  • **Public messages** — user-safe messages separate from technical details
  • **Low-cardinality messages** — variable data in `.With()` attributes, not the message string, so APM tools group errors properly

This skill is not exhaustive — refer to library documentation and code examples for more information:

  • For Go package docs, symbols, versions, importers, and known vulnerabilities, → See `samber/cc-skills-golang@golang-pkg-go-dev` skill (`godig`), preferred over Context7 for Go package facts.
  • To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See `samber/cc-skills-golang@golang-gopls` skill (`gopls`).
  • Context7 remains a fallback for docs not indexed on pkg.go.dev.

Core pattern: Error builder chain

All `oops` errors use a fluent builder pattern:

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")

Terminal methods:

  • `.Errorf(format, args...)` — create a new error
  • `.Wrap(err)` — wrap an existing error
  • `.Wrapf(err, format, args...)` — wrap with a message
  • `.Join(err1, err2, ...)` — combine multiple errors
  • `.Recover(fn)` / `.Recoverf(fn, format, args...)` — convert panic to error

Error builder methods

| Methods | Use case | | --- | --- | | `.With("key", value)` | Add custom key-value attribute (lazy `func() any` values supported) | | `.WithContext(ctx, "key1", "key2")` | Extract values from Go context into attributes (lazy values supported) | | `.In("domain")` | Set the feature/service/domain | | `.Tags("auth", "sql")` | Add categorization tags (query with `err.HasTag("tag")`) | | `.Code("iam_authz_missing_permission")` | Set machine-readable error identifier/slug | | `.Public("Could not fetch user.")` | Set user-safe message (separate from technical details) | | `.Hint("Runbook: https://doc.acme.org/doc/abcd.md")` | Add debugging hint for developers | | `.Owner("team/slack")` | Identify responsible team/owner | | `.User(id, "k", "v")` | Add user identifier and attributes | | `.Tenant(id, "k", "v")` | Add tenant/organization context and attributes | | `.Trace(id)` | Add trace / correlation ID (default: ULID) | | `.Span(id)` | Add span ID representing a unit of work/operation (default: ULID) | | `.Time(t)` | Override error timestamp (default: `time.Now()`) | | `.Since(t)` | Set duration based on time since `t` (exposed via `err.Duration()`) | | `.Duration(d)` | Set explicit error duration | | `.Request(req, includeBody)` | Attach `*http.Request` (optionally including body) | | `.Response(res, includeBody)` | Attach `*http.Response` (optionally including body) | | `oops.FromContext(ctx)` | Start from an `OopsErrorBuilder` stored in a Go context |

Common scenarios

Database/repository layer

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 handler layer

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

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

    w.WriteHeader(http.Statu
Read more
Ships withcc-skills-golang

AI agent skills are reusable instruction sets that extend your coding assistant with domain-specific expertise, loaded on demand so they don't bloat your context. This repository covers Go-specific skills only (language, testing, security, observability, etc.)

Get the whole plugin

Other skills on cc-skills-golang.