go / intermediate
Snippet
Retrieving Rich Context via Custom Error Structs and Unwrapping
In Go, errors can wrap other errors to provide contextual information while preserving the original error's type and details. By implementing the Unwrap() error method on a custom error struct, you allow functions like errors.Is and errors.As to inspect the error chain. This enables decoupled error handling where callers can inspect deep errors without tight coupling to the wrapper.
snippet.go
go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package mainimport ("errors""fmt")type QueryError struct {Query stringErr error}func (e *QueryError) Error() string {return fmt.Sprintf("query %q failed: %v", e.Query, e.Err)}func (e *QueryError) Unwrap() error {return e.Err}func executeQuery(query string) error {return &QueryError{Query: query,Err: errors.New("connection timeout"),}}func main() {err := executeQuery("SELECT * FROM users")if err != nil {var qErr *QueryErrorif errors.As(err, &qErr) {fmt.Printf("Custom error caught! Query: %s\n", qErr.Query)}}}
Breakdown
1
type QueryError struct {
Declares a custom error struct containing metadata (the query) and the underlying wrapped error.
2
func (e *QueryError) Error() string {
Implements the error interface, allowing QueryError to be used as a standard Go error.
3
func (e *QueryError) Unwrap() error {
Returns the nested error, enabling the standard library's error inspection helpers to traverse the chain.
4
if errors.As(err, &qErr) {
Checks if any error in the chain is of type QueryError, assigning it to qErr if found.