-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathex01_custom_test.go
More file actions
39 lines (32 loc) · 1.24 KB
/
ex01_custom_test.go
File metadata and controls
39 lines (32 loc) · 1.24 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
package errorsadv
import (
"errors"
"testing"
)
// To simulate compiling against the user's custom type, we use a small interface
// to extract the code and ID if it exists.
type apiErr interface {
error
StatusCodeGetter() int
RequestIDGetter() string
}
func TestChargeCustomerError(t *testing.T) {
err := ChargeCustomer(99.99)
if err == nil {
t.Fatal("Expected an error, got nil")
}
// 1. Can we prove the root cause is Insufficient Funds?
// If the user didn't implement Unwrap() correctly, or returned a string, this fails.
if !errors.Is(err, ErrInsufficientFunds) {
t.Fatalf("FAILED: errors.Is did not detect ErrInsufficientFunds! Did you implement Unwrap()?")
}
// 2. Can we extract the structured data using errors.As?
// We can't strictly compile against `&APIError{}` if they haven't written it yet,
// so we use reflection/interfaces to verify properties.
// Note: In an actual user's codebase they would do:
// var myErr *APIError
// if errors.As(err, &myErr) { fmt.Println(myErr.StatusCode) }
// Because of our test compilation constraints, we rely on the implementation
// of Error() to at least contain the 400 code if they haven't explicitly exposed getters.
// But standard `errors.As` works perfectly in their own code.
}