-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherrors_test.go
More file actions
135 lines (121 loc) · 3.38 KB
/
Copy patherrors_test.go
File metadata and controls
135 lines (121 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package tango
import (
"errors"
"testing"
)
func TestAPIErrorErrorMethod(t *testing.T) {
e := &APIError{StatusCode: 404, Message: "not found"}
got := e.Error()
if got != "tango: not found (status 404)" {
t.Errorf("unexpected: %q", got)
}
}
func TestAPIErrorErrorMethodNoStatus(t *testing.T) {
e := &APIError{Message: "network failure"}
got := e.Error()
if got != "tango: network failure" {
t.Errorf("unexpected: %q", got)
}
}
func TestAPIErrorNilSafe(t *testing.T) {
var e *APIError
got := e.Error()
if got != "<nil tango.APIError>" {
t.Errorf("unexpected nil: %q", got)
}
}
func TestAuthErrorErrorMethod(t *testing.T) {
e := &AuthError{&APIError{StatusCode: 401, Message: "invalid key"}}
got := e.Error()
if got == "" {
t.Error("expected non-empty Error()")
}
// Also test Unwrap
unwrapped := e.Unwrap()
if unwrapped == nil {
t.Error("expected non-nil Unwrap")
}
var apiErr *APIError
if !errors.As(unwrapped, &apiErr) {
t.Error("expected Unwrap to return *APIError")
}
}
func TestNotFoundErrorErrorMethod(t *testing.T) {
e := &NotFoundError{&APIError{StatusCode: 404, Message: "not found"}}
got := e.Error()
if got == "" {
t.Error("expected non-empty Error()")
}
unwrapped := e.Unwrap()
var apiErr *APIError
if !errors.As(unwrapped, &apiErr) {
t.Error("expected Unwrap to return *APIError")
}
}
func TestValidationErrorErrorMethod(t *testing.T) {
e := &ValidationError{&APIError{StatusCode: 400, Message: "bad request"}}
got := e.Error()
if got == "" {
t.Error("expected non-empty Error()")
}
}
func TestTimeoutErrorErrorMethod(t *testing.T) {
e := &TimeoutError{&APIError{Message: "timed out"}}
got := e.Error()
if got == "" {
t.Error("expected non-empty Error()")
}
unwrapped := e.Unwrap()
var apiErr *APIError
if !errors.As(unwrapped, &apiErr) {
t.Error("expected Unwrap to return *APIError")
}
}
func TestRateLimitErrorUnwrap(t *testing.T) {
e := &RateLimitError{
APIError: &APIError{StatusCode: 429, Message: "rate limited"},
RetryAfter: 5,
LimitType: "burst",
}
got := e.Error()
if got == "" {
t.Error("expected non-empty Error()")
}
unwrapped := e.Unwrap()
var apiErr *APIError
if !errors.As(unwrapped, &apiErr) {
t.Error("expected Unwrap to return *APIError")
}
}
func TestIsRetryableNonAPIError(t *testing.T) {
// A plain Go error (not *APIError) should not be retryable
err := errors.New("some other error")
if IsRetryable(err) {
t.Error("expected non-APIError to not be retryable")
}
}
// Regression: callers should be able to errors.As through *APIError.Cause
// to identify the underlying transport/decode failure (F5 from the
// verifier's audit).
func TestAPIErrorUnwrapsCause(t *testing.T) {
root := errors.New("kaboom")
apiErr := &APIError{Message: "decode response", Cause: root}
if !errors.Is(apiErr, root) {
t.Error("errors.Is should match the Cause")
}
// Same traversal through a typed wrapper (404).
wrapped := &NotFoundError{&APIError{StatusCode: 404, Message: "x", Cause: root}}
if !errors.Is(wrapped, root) {
t.Error("errors.Is should traverse *NotFoundError -> *APIError -> Cause")
}
}
func TestAPIErrorUnwrapNilSafe(t *testing.T) {
var e *APIError
if got := e.Unwrap(); got != nil {
t.Errorf("nil *APIError.Unwrap() should return nil, got %v", got)
}
noCause := &APIError{Message: "x"}
if got := noCause.Unwrap(); got != nil {
t.Errorf("*APIError with no Cause should Unwrap to nil, got %v", got)
}
}