Skip to content
This repository has been archived by the owner on Apr 8, 2019. It is now read-only.

[errors] Add functions to Wrap errors and preserve type #94

Merged
merged 2 commits into from
Sep 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@

package xerrors

import "bytes"
import (
"bytes"
"errors"
"fmt"
)

// FirstError will return the first non nil error
func FirstError(errs ...error) error {
Expand Down Expand Up @@ -80,6 +84,19 @@ type invalidParamsError struct {
containedError
}

// Wrap wraps an error with a message but preserves the type of the error.
func Wrap(err error, msg string) error {
renamed := errors.New(msg + ": " + err.Error())
return NewRenamedError(err, renamed)
}

// Wrapf formats according to a format specifier and uses that string to
// wrap an error while still preserving the type of the error.
func Wrapf(err error, format string, args ...interface{}) error {
msg := fmt.Sprintf(format, args...)
return Wrap(err, msg)
}

// NewInvalidParamsError creates a new invalid params error
func NewInvalidParamsError(inner error) error {
return invalidParamsError{containedError{inner}}
Expand Down
42 changes: 42 additions & 0 deletions errors/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,48 @@ import (
"github.com/stretchr/testify/require"
)

func TestWrap(t *testing.T) {
inner := errors.New("detailed error message")
err := NewInvalidParamsError(inner)
wrappedErr := Wrap(err, "context about params error")
assert.Error(t, wrappedErr)
assert.Equal(t, "context about params error: detailed error message", wrappedErr.Error())
assert.True(t, IsInvalidParams(wrappedErr))

err = NewRetryableError(inner)
wrappedErr = Wrap(err, "context about retryable error")
assert.Error(t, wrappedErr)
assert.Equal(t, "context about retryable error: detailed error message", wrappedErr.Error())
assert.True(t, IsRetryableError(wrappedErr))

err = NewNonRetryableError(inner)
wrappedErr = Wrap(err, "context about nonretryable error")
assert.Error(t, wrappedErr)
assert.Equal(t, "context about nonretryable error: detailed error message", wrappedErr.Error())
assert.True(t, IsNonRetryableError(wrappedErr))
}

func TestWrapf(t *testing.T) {
inner := errors.New("detailed error message")
err := NewInvalidParamsError(inner)
wrappedErr := Wrapf(err, "context about %s error", "params")
assert.Error(t, wrappedErr)
assert.Equal(t, "context about params error: detailed error message", wrappedErr.Error())
assert.True(t, IsInvalidParams(wrappedErr))

err = NewRetryableError(inner)
wrappedErr = Wrapf(err, "context about %s error", "retryable")
assert.Error(t, wrappedErr)
assert.Equal(t, "context about retryable error: detailed error message", wrappedErr.Error())
assert.True(t, IsRetryableError(wrappedErr))

err = NewNonRetryableError(inner)
wrappedErr = Wrapf(err, "context about %s error", "nonretryable")
assert.Error(t, wrappedErr)
assert.Equal(t, "context about nonretryable error: detailed error message", wrappedErr.Error())
assert.True(t, IsNonRetryableError(wrappedErr))
}

func TestMultiErrorNoError(t *testing.T) {
err := NewMultiError()
require.Nil(t, err.FinalError())
Expand Down