In Go, you can wrap and unwrap errors using the errors
package or by implementing the Unwrap
interface. This allows you to add additional context and information to an error while retaining the ability to access the underlying error.
Here's an example of how to wrap and unwrap errors:
Step 1: Define custom error type with a wrapped error field:
type MyError struct {
message string
err error
}
Step 2: Implement the error
interface for your custom error type:
func (e *MyError) Error() string {
return e.message
}
Step 3: Implement the Unwrap
method to access the underlying error:
func (e *MyError) Unwrap() error {
return e.err
}
Step 4: Wrap an existing error with additional context:
func doSomething() error {
err := someFunction()
if err != nil {
return &MyError{
message: "Error occurred while doing something",
err: err,
}
}
// ...
return nil
}
Step 5: Unwrap the error to access the underlying error information:
err := doSomething()
if err != nil {
if underlyingErr := errors.Unwrap(err); underlyingErr != nil {
fmt.Println("Underlying error:", underlyingErr)
}
fmt.Println("Error:", err)
}
Alternatively, you can also use the errors
package to wrap and unwrap errors:
err := fmt.Errorf("outer error: %w", innerErr)
To unwrap the error, you can use the errors.Is
function:
var innerErr SomeError
if errors.Is(err, &innerErr) {
// Handle inner error
}
Note that the errors.Is
function does not unwrap multiple layers of errors automatically. If you have multiple wrapped errors, you can use the errors.As
function to traverse the error chain:
var innerErr SomeError
if errors.As(err, &innerErr) {
// Handle inner error
}