Skip to content

Commit 4492269

Browse files
author
agilira
committed
Documentation update
1 parent 96add81 commit 4492269

File tree

14 files changed

+397
-225
lines changed

14 files changed

+397
-225
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,7 @@ jobs:
3535
go test -v -race -coverprofile=coverage.out -covermode=atomic ./...
3636
go tool cover -func=coverage.out
3737
38-
- name: Upload coverage to Codecov
39-
uses: codecov/codecov-action@v4
40-
with:
41-
file: ./coverage.out
42-
fail_ci_if_error: false
38+
4339
4440
quality:
4541
name: Code Quality

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Built for Styx, it includes error codes, stack traces, user messages, and JSON s
77
[![CI](https://github.com/agilira/go-errors/actions/workflows/ci.yml/badge.svg)](https://github.com/agilira/go-errors/actions/workflows/ci.yml)
88
[![Security](https://img.shields.io/badge/Security-gosec-brightgreen)](https://github.com/agilira/go-errors/actions/workflows/ci.yml)
99
[![Go Report Card](https://goreportcard.com/badge/github.com/agilira/go-errors)](https://goreportcard.com/report/github.com/agilira/go-errors)
10-
[![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)](https://github.com/agilira/go-errors/actions/workflows/ci.yml)
10+
[![Coverage](https://img.shields.io/badge/coverage-86%25-brightgreen)](https://github.com/agilira/go-errors/actions/workflows/ci.yml)
1111

1212
## Features
1313
- Structured error type: code, message, context, cause, severity
@@ -39,6 +39,18 @@ func validateUser(username string) error {
3939
}
4040
```
4141

42+
## JSON Output
43+
Errors automatically serialize to structured JSON:
44+
```go
45+
err := errors.New("VALIDATION_ERROR", "Email format invalid").
46+
WithUserMessage("Please enter a valid email address").
47+
WithContext("field", "email").
48+
WithSeverity("warning")
49+
50+
jsonData, _ := json.Marshal(err)
51+
// Output: {"code":"VALIDATION_ERROR","message":"Email format invalid","user_msg":"Please enter a valid email address","context":{"field":"email"},"severity":"warning","timestamp":"2025-01-27T10:30:00Z",...}
52+
```
53+
4254
## Testing & Coverage
4355
Run all tests:
4456
```sh

ROADMAP.md

Lines changed: 0 additions & 161 deletions
This file was deleted.

doc.go

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
// Package errors provides structured, contextual error handling for Go applications.
2+
//
3+
// # Overview
4+
//
5+
// This package offers a comprehensive error handling system designed for modern Go applications.
6+
// It provides structured error types with rich metadata, stack traces, user-friendly messages,
7+
// and JSON serialization capabilities. Built for microservices and API development, it enables
8+
// consistent error handling across your entire application stack.
9+
//
10+
// # Key Features
11+
//
12+
// • Structured Error Types: Errors include codes, messages, context, timestamps, and severity levels
13+
// • Stack Trace Support: Optional lightweight stack traces for debugging
14+
// • User-Friendly Messages: Separate technical and user-facing error messages
15+
// • JSON Serialization: Built-in JSON marshaling for API responses and logging
16+
// • Retry Logic: Built-in support for retryable errors
17+
// • Interface-Based: Type-safe error handling through well-defined interfaces
18+
// • Zero Dependencies: Uses only Go standard library
19+
// • High Performance: Minimal overhead with efficient memory usage
20+
//
21+
// # Quick Start
22+
//
23+
// Create a new error with a custom code:
24+
//
25+
// const ErrCodeValidation = "VALIDATION_ERROR"
26+
// err := errors.New(ErrCodeValidation, "Username is required")
27+
//
28+
// Add user-friendly message and context:
29+
//
30+
// err = err.WithUserMessage("Please enter a username").
31+
// WithContext("field", "username").
32+
// WithSeverity("warning")
33+
//
34+
// Wrap existing errors with additional context:
35+
//
36+
// if err := someOperation(); err != nil {
37+
// return errors.Wrap(err, ErrCodeOperation, "Failed to process request")
38+
// }
39+
//
40+
// Check error codes programmatically:
41+
//
42+
// if errors.HasCode(err, ErrCodeValidation) {
43+
// // Handle validation error
44+
// }
45+
//
46+
// # JSON Serialization
47+
//
48+
// Errors automatically serialize to JSON with all metadata:
49+
//
50+
// jsonData, _ := json.Marshal(err)
51+
// // Output: {"code":"VALIDATION_ERROR","message":"Username is required",...}
52+
//
53+
// # Interface-Based Error Handling
54+
//
55+
// Use interfaces for type-safe error handling:
56+
//
57+
// var coder errors.ErrorCoder = err
58+
// code := coder.ErrorCode()
59+
//
60+
// var retry errors.Retryable = err
61+
// if retry.IsRetryable() {
62+
// // Implement retry logic
63+
// }
64+
//
65+
// var um errors.UserMessager = err
66+
// userMsg := um.UserMessage()
67+
//
68+
// # Best Practices
69+
//
70+
// 1. Define error codes as constants in your application
71+
// 2. Use WithUserMessage() for errors that will be displayed to users
72+
// 3. Use WithContext() to add debugging information
73+
// 4. Use Wrap() to add context to errors from lower-level functions
74+
// 5. Use AsRetryable() for transient errors that can be retried
75+
// 6. Use different severity levels for different types of errors
76+
//
77+
// # Error Severity Levels
78+
//
79+
// • "error": Standard application errors (default)
80+
// • "warning": Non-critical issues that should be noted
81+
// • "info": Informational messages
82+
// • "critical": Severe errors that require immediate attention
83+
//
84+
// # Integration Examples
85+
//
86+
// REST API Handler:
87+
//
88+
// func handleRequest(w http.ResponseWriter, r *http.Request) {
89+
// err := processRequest(r)
90+
// if err != nil {
91+
// apiErr, ok := err.(*errors.Error)
92+
// if ok {
93+
// http.Error(w, apiErr.UserMessage(), getStatusCode(apiErr))
94+
// log.Error("API Error", "error", apiErr.Error(), "code", apiErr.ErrorCode())
95+
// } else {
96+
// http.Error(w, "Internal server error", 500)
97+
// }
98+
// }
99+
// }
100+
//
101+
// Database Operations:
102+
//
103+
// func saveUser(user *User) error {
104+
// if err := db.Save(user); err != nil {
105+
// return errors.Wrap(err, ErrCodeDatabase, "Failed to save user").
106+
// WithContext("user_id", user.ID).
107+
// WithUserMessage("Unable to save your information. Please try again.")
108+
// }
109+
// return nil
110+
// }
111+
//
112+
// Validation:
113+
//
114+
// func validateUser(user *User) error {
115+
// if user.Email == "" {
116+
// return errors.NewWithField(ErrCodeValidation, "Email is required", "email", user.Email).
117+
// WithUserMessage("Please provide a valid email address")
118+
// }
119+
// return nil
120+
// }
121+
//
122+
// # Testing
123+
//
124+
// Use table-driven tests for error scenarios:
125+
//
126+
// func TestValidation(t *testing.T) {
127+
// tests := []struct {
128+
// name string
129+
// input string
130+
// wantErr bool
131+
// wantCode errors.ErrorCode
132+
// }{
133+
// {"valid email", "user@example.com", false, ""},
134+
// {"empty email", "", true, ErrCodeValidation},
135+
// }
136+
//
137+
// for _, tt := range tests {
138+
// t.Run(tt.name, func(t *testing.T) {
139+
// err := validateEmail(tt.input)
140+
// if tt.wantErr {
141+
// assert.True(t, errors.HasCode(err, tt.wantCode))
142+
// } else {
143+
// assert.NoError(t, err)
144+
// }
145+
// })
146+
// }
147+
// }
148+
//
149+
// # Performance Considerations
150+
//
151+
// • Stack traces are only captured when using Wrap() or explicitly requested
152+
// • JSON marshaling is optimized for common use cases
153+
// • Memory usage is minimal with efficient struct layout
154+
// • No reflection is used in hot paths
155+
//
156+
// # Migration from Standard Errors
157+
//
158+
// Replace standard error creation:
159+
//
160+
// // Before
161+
// return errors.New("validation failed")
162+
//
163+
// // After
164+
// return errors.New(ErrCodeValidation, "validation failed")
165+
//
166+
// Replace error wrapping:
167+
//
168+
// // Before
169+
// return fmt.Errorf("operation failed: %w", err)
170+
//
171+
// // After
172+
// return errors.Wrap(err, ErrCodeOperation, "operation failed")
173+
//
174+
// Copyright (c) 2025 AGILira
175+
// Series: an AGLIra library
176+
// SPDX-License-Identifier: MPL-2.0
177+
package errors

0 commit comments

Comments
 (0)