Skip to content

Commit

Permalink
use errors.As instead of type assertion in IsError functions
Browse files Browse the repository at this point in the history
This allows IsRedirect to detect a Redirect error even if
it's wrapped via fmt.Errorf("some description: %w", err).
  • Loading branch information
dmitshur committed Sep 6, 2021
1 parent 98753a9 commit 9bb3cab
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
15 changes: 10 additions & 5 deletions error.go
Expand Up @@ -21,7 +21,8 @@ func (m Method) Error() string {

// IsMethod reports if err is considered a method error, returning it if so.
func IsMethod(err error) (Method, bool) {
e, ok := err.(Method)
var e Method
ok := errors.As(err, &e)
return e, ok
}

Expand All @@ -34,7 +35,8 @@ func (r Redirect) Error() string { return fmt.Sprintf("redirecting to %s", r.URL

// IsRedirect reports if err is considered a redirect, returning it if so.
func IsRedirect(err error) (Redirect, bool) {
e, ok := err.(Redirect)
var e Redirect
ok := errors.As(err, &e)
return e, ok
}

Expand All @@ -48,7 +50,8 @@ func (b BadRequest) Error() string { return b.Err.Error() }

// IsBadRequest reports if err is considered a bad request error, returning it if so.
func IsBadRequest(err error) (BadRequest, bool) {
e, ok := err.(BadRequest)
var e BadRequest
ok := errors.As(err, &e)
return e, ok
}

Expand All @@ -63,7 +66,8 @@ func (h HTTP) Error() string { return h.Err.Error() }

// IsHTTP reports if err is considered an HTTP error, returning it if so.
func IsHTTP(err error) (HTTP, bool) {
e, ok := err.(HTTP)
var e HTTP
ok := errors.As(err, &e)
return e, ok
}

Expand All @@ -76,6 +80,7 @@ func (JSONResponse) Error() string { return "JSONResponse" }

// IsJSONResponse reports if err is considered a JSON response, returning it if so.
func IsJSONResponse(err error) (JSONResponse, bool) {
e, ok := err.(JSONResponse)
var e JSONResponse
ok := errors.As(err, &e)
return e, ok
}
28 changes: 28 additions & 0 deletions error_test.go
@@ -0,0 +1,28 @@
package httperror_test

import (
"fmt"
"testing"

"github.com/shurcooL/httperror"
)

func TestIsRedirect(t *testing.T) {
for _, tt := range [...]struct {
name string
in error
want bool
}{
{name: "bare", in: httperror.Redirect{URL: "u"}, want: true},
{name: "wrapped in %w", in: fmt.Errorf("desc: %w", httperror.Redirect{URL: "u"}), want: true},
{name: "wrapped in %v", in: fmt.Errorf("desc: %v", httperror.Redirect{URL: "u"}), want: false},
{name: "not redirect", in: httperror.Method{Allowed: []string{"GET"}}, want: false},
} {
t.Run(tt.name, func(t *testing.T) {
_, got := httperror.IsRedirect(tt.in)
if got != tt.want {
t.Errorf("got = %v, want %v", got, tt.want)
}
})
}
}
3 changes: 3 additions & 0 deletions go.mod
@@ -0,0 +1,3 @@
module github.com/shurcooL/httperror

go 1.17

0 comments on commit 9bb3cab

Please sign in to comment.