Skip to content

[refactor] Standardize error aggregation and wrapping with multierr #118

@kangeunchan

Description

@kangeunchan

Enhancement Description

Standardize error aggregation and wrapping patterns using go.uber.org/multierr and consistent error-chain semantics.
Scope type: Error handling consistency and developer ergonomics

Background

Error handling varies across the codebase. Custom multi-error aggregation does not support Go 1.20+ Unwrap() []error semantics, reducing usefulness of errors.Is/As and weakening debugging.

Scope

Replace custom MultiError with multierr.Append

  • Files: internal/** (where custom MultiError exists, e.g., docker package)
  • Files: go.mod (already depends on multierr; confirm versions)

Ensure custom errors support chaining consistently

  • Implement Unwrap() and/or Is() consistently where required
  • Prefer fmt.Errorf(... %w ...) for wrapping at boundaries

Add context to operational errors

  • Include paths/parameters where meaningful
  • Avoid generic “failed” without actionable context

Document guidelines

  • Files: CONTRIBUTING.md (or docs/dev/*)

Non-Goals

  • Rewriting all errors in the repository in one pass
  • Introducing new error frameworks or logging libraries
  • Changing user-facing error text wholesale without reason

Risks and Open Questions

  • Some error messages are relied upon by scripts; changes must be scoped and noted
  • Aggregation semantics must preserve ordering and readability
  • Need to avoid leaking sensitive data in error contexts

Validation Plan

Unit and Integration Checks

  • go test ./... for affected packages
  • Unit tests demonstrating errors.Is/As works through aggregates
  • Static checks for removed custom MultiError usage (grep)

End-to-End Checks

  • Smoke critical workflows to ensure errors remain actionable
  • Validate multi-error outputs remain readable in CLI logs

Evidence Required in Issue Updates

  • Before/after example showing errors.Is/As works for aggregated errors
  • Grep evidence showing custom MultiError removed
  • Snippets of improved error messages with context

Acceptance Criteria

  • Custom MultiError usage removed in favor of multierr
  • errors.Is/As works reliably for aggregated errors
  • Error wrapping guidelines documented
  • Operational errors include actionable context

Deliverables

  • PR replacing custom MultiError and updating call sites
  • PR documenting error guidelines (if separate)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions