0 day streak
go / intermediate
Snippet

Implementing Custom Error Types with Unwrap Support

In Go, errors can wrap other errors to provide context. By implementing an Unwrap() method returning 'error', a custom error type enables standard library functions like errors.Is and errors.As to inspect the error chain recursively. This separates the high-level contextual error from the low-level root cause.

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
package main
import (
"errors"
"fmt"
)
type QueryError struct {
Query string
Err 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 main() {
baseErr := errors.New("permission denied")
err := &QueryError{Query: "SELECT * FROM users", Err: baseErr}
if errors.Is(err, baseErr) {
fmt.Println("Underlying error is 'permission denied'")
}
}
Breakdown
1
type QueryError struct {
Defines a custom error struct containing contextual information (Query) and the underlying error (Err).
2
func (e *QueryError) Error() string {
Implements the error interface, formatting the error message with both context and the inner error.
3
func (e *QueryError) Unwrap() error {
Returns the wrapped error, which allows standard library functions to access the nested error.
4
if errors.Is(err, baseErr) {
Uses errors.Is to verify if the base error is present anywhere in the error chain.