fleet
fleet copied to clipboard
"unwrap" pkg/errors errors in the transport encoder
We use the errors.Wrap(err, "additional info about the error")
patter to wrap increasingly more errors in the app.
This is great, but the error is wrapped into a new type to add context.
Inside the encodeError
function in transport_error.go
we might need to "unwrap" the error in at the top of the errorEncoder function to determine it's type in order to properly encode it to the client.
example:
package main
import (
"testing"
"github.com/pkg/errors"
)
package main
import (
"fmt"
"testing"
"github.com/pkg/errors"
)
func TestUnwrap(t *testing.T) {
// passes
if err := base(); err != baseError {
t.Errorf("expected base error, got %s", err)
}
// fails:
// main_test.go:16: expected base error, got additional context: an error
if err := wrapped(baseError); err != baseError {
t.Errorf("expected base error, got %s", err)
}
// passes
if err := wrapped(baseError); errors.Cause(err) != baseError {
t.Errorf("expected base error, got %s", err)
}
// Or with wrapped typed errors
type Retriable interface {
error
Temporary() bool
}
var rErr error
rErr = &e{}
rErr = wrapped(rErr) // wrap here
if e, ok := rErr.(Retriable); ok {
// will never print because it's wrapped
fmt.Println(e.Error())
}
}
func wrapped(err error) error {
return errors.Wrap(err, "additional context")
}
type e struct{}
func (err *e) Error() string {
return "an error"
}
func (err *e) Temporary() bool {
return true
}
var baseError = errors.New("an error")
func base() error {
return baseError
}