Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copilot Instructions for github.com/goark/errs

## Project Overview
- This repository provides `github.com/goark/errs`, a Go package for structured error wrapping and multi-error handling.
- Main module target is Go 1.20+.
- There is a nested module under `zapobject/` that should stay in sync with top-level changes when relevant.
- If dependency or Go-version related files are changed, keep `go.mod` (root), `zapobject/go.mod`, and `go.work` consistency in mind.

## Coding Guidelines
- Keep public APIs backward compatible unless explicitly requested.
- Follow idiomatic Go naming and error handling patterns.
- Keep code comments in English.
- Avoid introducing new dependencies unless there is a clear benefit.

## Testing and Validation
- Prefer `task` commands for local validation.
- Primary checks:
- `task test`
- `task govulncheck`
- For broad validation, run:
- `task`
- Before proposing a merge, run at least `task test` and `task govulncheck`. For wide-ranging changes, run `task`.

## CI/Workflow Expectations
- Keep GitHub Actions workflows minimal and readable.
- CI should cover lint, tests, and reachable-vulnerability checks.
- Keep workflow action versions reasonably up to date.
- Keep `ci.yml` split into independent jobs for lint/test and govulncheck where possible for faster feedback.
- Use `golang/govulncheck-action` for govulncheck in CI unless there is a strong reason to change.

## Documentation Expectations
- When behavior or developer flow changes, update `README.md` in the same change.
- Keep usage examples executable and aligned with current API.
- Keep README links to sample programs under `sample/` and `zapobject/` aligned with current behavior.

## API and Compatibility Notes
- Do not introduce new usage of deprecated `Cause()`; prefer `errors.Is`/`errors.As` compatible flows and `Unwrap`/`Unwraps`.
- Treat changes to exported symbols, function signatures, and observable error formatting behavior as potentially breaking.
- Error string and JSON formatting are validated by tests; when output behavior changes, update README examples and test expectations in the same change.
64 changes: 64 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: ci

on:
push:
branches:
- master
pull_request:

permissions:
contents: read

jobs:
test-and-lint:
name: lint and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- uses: actions/setup-go@v6
with:
go-version-file: go.mod
cache-dependency-path: |
go.sum
zapobject/go.sum

- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: latest
args: --enable gosec

- name: Test root module
run: go test -shuffle on ./...

- name: Test zapobject module
working-directory: zapobject
run: go test -shuffle on ./...

govulncheck-root:
name: govulncheck (root)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Run govulncheck for root module
uses: golang/govulncheck-action@v1
with:
go-version-file: go.mod
go-package: ./...
repo-checkout: false

govulncheck-zapobject:
name: govulncheck (zapobject)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Run govulncheck for zapobject module
uses: golang/govulncheck-action@v1
with:
work-dir: zapobject
go-version-file: go.mod
go-package: ./...
repo-checkout: false
58 changes: 0 additions & 58 deletions .github/workflows/codeql-analysis.yml

This file was deleted.

35 changes: 35 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: CodeQL

on:
push:
branches:
- master
pull_request:
branches:
- master
schedule:
- cron: "0 20 * * 0"

permissions:
actions: read
contents: read
security-events: write

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: go

- name: Autobuild
uses: github/codeql-action/autobuild@v3

- name: Perform CodeQL analysis
uses: github/codeql-action/analyze@v3
50 changes: 0 additions & 50 deletions .github/workflows/lint.yml

This file was deleted.

19 changes: 0 additions & 19 deletions .github/workflows/vulns.yml

This file was deleted.

89 changes: 87 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# [errs] -- Error handling for Golang

[![check vulns](https://github.com/goark/errs/workflows/vulns/badge.svg)](https://github.com/goark/errs/actions)
[![lint status](https://github.com/goark/errs/workflows/lint/badge.svg)](https://github.com/goark/errs/actions)
[![ci status](https://github.com/goark/errs/workflows/ci/badge.svg)](https://github.com/goark/errs/actions)
[![codeql status](https://github.com/goark/errs/workflows/CodeQL/badge.svg)](https://github.com/goark/errs/actions)
[![GitHub license](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://raw.githubusercontent.com/goark/errs/master/LICENSE)
[![GitHub release](http://img.shields.io/github/release/goark/errs.svg)](https://github.com/goark/errs/releases/latest)

Expand All @@ -10,8 +10,79 @@ This package is required Go 1.20 or later.

**Migrated repository to [github.com/goark/errs][errs]**

## Design goals

- Wrap any `error` and collect context at the point of failure
- Add arbitrary key/value context with `WithContext`
- Include caller function name in context by default
- Print structured error data with `%+v` (JSON-like output)
- Handle multi-errors in a concurrency-safe way via `errs.Errors`

## Development

### Requirements

- Go 1.20 or later
- [Task](https://taskfile.dev/) command

### Local validation

```text
task test
task govulncheck
```

Run all maintenance tasks:

```text
task
```

## CI Workflows

- `ci`: lint (`golangci-lint` with `gosec`), tests, and `govulncheck`
- `CodeQL`: scheduled and push/PR static analysis

## Usage

### Sample programs

All sample files under `sample/` use the `run` build tag.

```text
go run -tags run ./sample/sample1.go
```

- New error with cause and context: [sample/sample1.go](sample/sample1.go)
- Wrap existing error with context: [sample/sample2.go](sample/sample2.go)
- Wrap sentinel error with cause: [sample/sample3.go](sample/sample3.go)
- Multiple causes with `errors.Join`: [sample/sample4.go](sample/sample4.go)
- Multi-error with `errs.Join`: [sample/sample5.go](sample/sample5.go)
- Concurrency-safe multi-error accumulation: [sample/sample6.go](sample/sample6.go)
- Zap structured logging object example: [zapobject/example_test.go](zapobject/example_test.go)

### Print formats

- `%v`: human readable error message
- `%#v`: Go-syntax-like internal structure
- `%+v`: structured JSON-like representation

### Helper functions compatible with stdlib

`errs.Is`, `errs.As`, and `errs.Unwrap` are thin wrappers around `errors.Is`, `errors.As`, and `errors.Unwrap`.

`errs.Unwraps` returns `[]error` and works for both single-cause and multi-cause errors.
For a single cause, it returns a one-element slice.
For multiple causes, it returns all causes as a slice.

`errs.EncodeJSON` serializes generic `error` values by traversing unwrap chains when possible.

### Edge-case behavior

- `errs.New("")` returns `nil`
- `errs.Wrap(nil)` returns `nil`
- If `WithCause` is given multiple times, the last cause is used

### Create new error instance with cause

```go
Expand Down Expand Up @@ -198,4 +269,18 @@ func main() {
}
```

### Structured logging with Zap

Use the submodule `github.com/goark/errs/zapobject` to log errors as structured objects.

```go
logger.Error("failed", zap.Object("error", zapobject.New(err)))
```

Without `zapobject`, `zap.Error(err)` writes string fields only.

## Background article (Japanese)

- [Go 言語用エラーハンドリング・パッケージ](https://text.baldanders.info/release/errs-package-for-golang/)

[errs]: https://github.com/goark/errs "goark/errs: Error handling for Golang"
Loading