How to Unwrap Error in Go: Simple Guide with Examples
In Go, you can unwrap an error using the
errors.Unwrap function, which returns the next error in the chain if the error wraps another. This helps you access the original error inside wrapped errors created with fmt.Errorf and the %w verb.Syntax
The errors.Unwrap function takes an error and returns the wrapped error inside it, or nil if there is none.
Usage pattern:
func Unwrap(err error) error
Here:
erris the error you want to unwrap.- The function returns the inner error wrapped by
err, ornilif no wrapped error exists.
go
package main import ( "errors" "fmt" ) func main() { var originalErr = errors.New("original error") wrappedErr := fmt.Errorf("wrapped: %w", originalErr) unwrappedErr := errors.Unwrap(wrappedErr) fmt.Println("Unwrapped error:", unwrappedErr) }
Output
Unwrapped error: original error
Example
This example shows how to create a wrapped error and then unwrap it to get the original error.
go
package main import ( "errors" "fmt" ) func main() { // Create the original error originalErr := errors.New("file not found") // Wrap the original error with more context wrappedErr := fmt.Errorf("read config failed: %w", originalErr) // Unwrap to get the original error unwrappedErr := errors.Unwrap(wrappedErr) fmt.Println("Wrapped error:", wrappedErr) fmt.Println("Unwrapped error:", unwrappedErr) }
Output
Wrapped error: read config failed: file not found
Unwrapped error: file not found
Common Pitfalls
One common mistake is trying to unwrap an error that is not wrapped, which returns nil. Also, unwrapping only goes one level deep, so to get the original error in a chain, you may need to unwrap repeatedly.
Another pitfall is using %v instead of %w when wrapping errors, which prevents unwrapping.
go
package main import ( "errors" "fmt" ) func main() { originalErr := errors.New("network error") // Wrong wrapping: using %v does NOT wrap the error wrongWrap := fmt.Errorf("failed: %v", originalErr) // Correct wrapping: using %w wraps the error correctWrap := fmt.Errorf("failed: %w", originalErr) fmt.Println("Unwrap wrongWrap:", errors.Unwrap(wrongWrap)) // <nil> fmt.Println("Unwrap correctWrap:", errors.Unwrap(correctWrap)) // network error }
Output
Unwrap wrongWrap: <nil>
Unwrap correctWrap: network error
Quick Reference
Tips for unwrapping errors in Go:
- Use
errors.Unwrap(err)to get the wrapped error. - Wrap errors with
fmt.Errorf("%w")to enable unwrapping. - To check error chains, use
errors.Isorerrors.Asfor safer error handling. - Unwrapping only unwraps one level; loop if you need the root cause.
Key Takeaways
Use errors.Unwrap to get the inner error wrapped inside another error.
Wrap errors with fmt.Errorf and the %w verb to enable unwrapping.
Unwrap returns nil if the error does not wrap another error.
Unwrapping only goes one level deep; loop to reach the original error.
Use errors.Is and errors.As for common error checks in wrapped chains.