65 lines
2.1 KiB
Go
65 lines
2.1 KiB
Go
package errkind_test
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"net/url"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"git.d-ma.be/mathias/tapir/internal/errkind"
|
|
)
|
|
|
|
// Of reduces an error to a short kind that is safe to log, store and show: it never
|
|
// carries the error's own text, because that text can hold a provider's response body, a
|
|
// file path or a word from a private transcript (ADR-035 review F3, F5).
|
|
|
|
type statusErr struct{ code int }
|
|
|
|
func (e statusErr) Error() string {
|
|
return fmt.Sprintf("gateway said: %d and echoed the transcript", e.code)
|
|
}
|
|
func (e statusErr) HTTPStatus() int { return e.code }
|
|
|
|
type timeoutNet struct{}
|
|
|
|
func (timeoutNet) Error() string { return "i/o timeout to 10.0.0.1" }
|
|
func (timeoutNet) Timeout() bool { return true }
|
|
func (timeoutNet) Temporary() bool { return true }
|
|
|
|
func TestOf_ReducesAnErrorToAKindAndNeverItsText(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
err error
|
|
want string
|
|
}{
|
|
{"nothing", nil, ""},
|
|
{"a deadline", context.DeadlineExceeded, "timeout"},
|
|
{"a wrapped deadline", fmt.Errorf("transcribe: %w", context.DeadlineExceeded), "timeout"},
|
|
{"a cancellation", fmt.Errorf("job: %w", context.Canceled), "canceled"},
|
|
{"an HTTP status", statusErr{code: 502}, "http_502"},
|
|
{"a wrapped HTTP status", fmt.Errorf("model: %w", statusErr{code: 400}), "http_400"},
|
|
{"a network timeout", timeoutNet{}, "timeout"},
|
|
{"a network failure", &net.OpError{Op: "dial", Err: errors.New("connection refused")}, "network"},
|
|
{"a url error wrapping a refusal", &url.Error{Op: "Post", URL: "http://gateway/secret-path", Err: errors.New("refused")}, "network"},
|
|
{"anything else", errors.New("moov atom not found in /spool/upload-555"), "error"},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert.Equal(t, tt.want, errkind.Of(tt.err))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestOf_AKindCarriesNoWordFromTheError(t *testing.T) {
|
|
err := fmt.Errorf("convert /spool/upload-555: %w", errors.New("Anders ansvarar för virket"))
|
|
|
|
got := errkind.Of(err)
|
|
|
|
assert.NotContains(t, got, "Anders")
|
|
assert.NotContains(t, got, "spool")
|
|
}
|