-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy patherrors.go
More file actions
141 lines (126 loc) · 3.55 KB
/
errors.go
File metadata and controls
141 lines (126 loc) · 3.55 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
136
137
138
139
140
141
package maxigo
import (
"errors"
"fmt"
)
// ErrEmptyToken is returned when an empty token is passed to New.
var ErrEmptyToken = errors.New("bot token is empty")
// ErrPollDeadline is returned by [Client.GetUpdates] when the context deadline
// is too short for the requested long-polling timeout.
var ErrPollDeadline = errors.New("context deadline is shorter than polling timeout + buffer; increase the deadline or reduce GetUpdatesOpts.Timeout")
// ErrorKind classifies the category of an error returned by the client.
type ErrorKind int
const (
// ErrAPI indicates the Max Bot API returned a non-200 HTTP response.
ErrAPI ErrorKind = iota
// ErrNetwork indicates an HTTP transport failure (connection refused, DNS, etc.).
ErrNetwork
// ErrTimeout indicates the request timed out or the context deadline was exceeded.
ErrTimeout
// ErrDecode indicates a JSON marshal or unmarshal failure.
ErrDecode
// ErrFetch indicates a failure when downloading from an external URL
// (used by UploadPhotoFromURL and UploadMediaFromURL).
ErrFetch
)
// String returns a human-readable name for the error kind.
func (k ErrorKind) String() string {
switch k {
case ErrAPI:
return "api"
case ErrNetwork:
return "network"
case ErrTimeout:
return "timeout"
case ErrDecode:
return "decode"
case ErrFetch:
return "fetch"
default:
return "unknown"
}
}
// Error represents any error produced by the maxigo client.
//
// Use [errors.As] to extract the Error and inspect its fields:
//
// var e *maxigo.Error
// if errors.As(err, &e) {
// switch e.Kind {
// case maxigo.ErrAPI:
// log.Printf("API error %d: %s", e.StatusCode, e.Message)
// case maxigo.ErrTimeout:
// log.Printf("timeout in %s", e.Op)
// }
// }
type Error struct {
// Kind classifies the error category.
Kind ErrorKind
// StatusCode is the HTTP status code. Only set when Kind is ErrAPI.
StatusCode int
// Message is a human-readable error description.
Message string
// Op is the client operation that failed (e.g. "SendMessage", "GetChat").
Op string
// Err is the underlying error, if any.
Err error
}
// Error returns a formatted error string including the operation, kind, and details.
func (e *Error) Error() string {
if e.Kind == ErrAPI || e.Kind == ErrFetch {
return fmt.Sprintf("%s: %s error %d: %s", e.Op, e.Kind, e.StatusCode, e.Message)
}
if e.Message != "" {
return fmt.Sprintf("%s: %s: %s", e.Op, e.Kind, e.Message)
}
return fmt.Sprintf("%s: %s", e.Op, e.Kind)
}
// Unwrap returns the underlying error for use with [errors.Is] and [errors.As].
func (e *Error) Unwrap() error {
return e.Err
}
// Timeout reports whether the error represents a timeout.
// This implements the informal timeout interface used by [net.Error].
func (e *Error) Timeout() bool {
return e.Kind == ErrTimeout
}
func apiError(op string, statusCode int, message string) *Error {
return &Error{
Kind: ErrAPI,
StatusCode: statusCode,
Message: message,
Op: op,
}
}
func networkError(op string, err error) *Error {
return &Error{
Kind: ErrNetwork,
Message: err.Error(),
Op: op,
Err: err,
}
}
func timeoutError(op string, err error) *Error {
return &Error{
Kind: ErrTimeout,
Message: err.Error(),
Op: op,
Err: err,
}
}
func decodeError(op string, err error) *Error {
return &Error{
Kind: ErrDecode,
Message: err.Error(),
Op: op,
Err: err,
}
}
func fetchError(op string, statusCode int, message string) *Error {
return &Error{
Kind: ErrFetch,
StatusCode: statusCode,
Message: message,
Op: op,
}
}