# Golang Samber Oops

> Create, wrap, expose, log, or test structured errors with `github.com/samber/oops`, including codes, attributes, public messages, stacks, context builders, and panic recovery. Use when a project already uses oops or deliberately adopts its structured error contract.

- Skill: `reagin/golang-samber-oops` (Agent Skill)
- Install (CLI): `npx skillmds@latest add reagin/golang-samber-oops`
- Raw SKILL.md: https://api.skillmd.com/api/skills/reagin/golang-samber-oops/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: reagin (https://skillmd.com/u/reagin)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/reagin/golang-samber-oops

---


# samber/oops structured errors

Inspect `go.mod`, local builder helpers, transport mapping, `errors.Is`/`errors.As` checks, logger formatting, recovery middleware, and tests. Preserve the project's code vocabulary, public-message policy, stack policy, and redaction rules.

## Build the intended error contract

The fluent builder surface is version-sensitive. Common categories include:

| Purpose | Representative API |
| --- | --- |
| Domain and classification | `In`, `Tags`, `Code` |
| Diagnostic attributes | `With`, `WithContext`, `Hint`, `Owner` |
| Identity and tracing | `User`, `Tenant`, `Trace`, `Span` |
| Safe client text | `Public` |
| Timing and protocol context | `Time`, `Since`, `Duration`, `Request`, `Response` |
| Context reuse | `WithBuilder`, `FromContext` |

Verify signatures and data captured by each builder in the pinned release. In particular, request and response helpers may optionally capture bodies, headers, or URLs that require redaction.

Use a stable `Code` when callers, transport adapters, metrics, or retry decisions depend on it. Keep variable diagnostics in attributes when the logging backend groups on message, while respecting its cardinality model. Public messages and internal messages are separate contracts.

## Choose the terminal operation

Representative terminal methods include:

- `Errorf` for a new structured error;
- `Wrap` or `Wrapf` for retaining an underlying cause;
- `Join` for several independent failures;
- `Recover` or `Recoverf` for a deliberate panic boundary.

Check nil behavior before replacing `if err != nil`: releases may define `Wrap(nil)` as `nil`, but local wrappers can change that contract. Confirm that wrapping preserves the unwrap chain needed by `errors.Is` and `errors.As`.

Add context at the layer that knows it. Repeated wrapping is useful only when each layer contributes a stable code, public mapping, ownership detail, or diagnostic attribute. Log at the boundary that owns the outcome so the same failure is not emitted repeatedly.

## Access and transport mapping

Prefer standard `errors.As` or the package's supported accessor to obtain the structured error type. Read codes, public text, attributes, tags, domain, trace data, and stack through APIs present in the selected version.

Map errors to HTTP, RPC, CLI, or job outcomes through stable fields rather than parsing `Error()` text. Preserve the original cause internally while emitting only approved public text and fields externally. Attributes, stack frames, hints, user data, and request metadata all require the same sensitivity review as log fields.

## Panic recovery

Recovery belongs at an isolation boundary with a defined failure outcome: an HTTP request, worker item, plugin callback, or owned top-level goroutine. Convert the panic to an error, report it once, and terminate or fail that unit of work. Confirm whether the selected recovery helper catches all panic values and what stack it captures.

Assertions and package-global stack/source settings affect process-wide behavior. Change them only when the application owns that policy and tests do not run conflicting configurations concurrently.

## Verification

Test new-error, wrapped-error, joined-error, and recovered-panic paths that the change touches. Assert stable codes, public messages, attributes, `errors.Is`/`errors.As`, transport status, redaction, and stack presence rather than the entire diagnostic string. Include nil wrapping and malformed context data where relevant.

Use a recording logger or formatter to verify the actual exported fields without sending test events to a remote backend.

## References

- [package documentation](https://pkg.go.dev/github.com/samber/oops)
- [repository](https://github.com/samber/oops)

