Repository navigation
Expand file tree
/
Copy patherrors.go
More file actions
60 lines (51 loc) · 2.31 KB
/
Copy patherrors.go
File metadata and controls
60 lines (51 loc) · 2.31 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
package openwa
import (
"errors"
"fmt"
)
var (
ErrInvalidConfig = errors.New("openwa: invalid client configuration")
ErrInvalidInput = errors.New("openwa: invalid operation input")
ErrTransport = errors.New("openwa: HTTP request failed")
ErrInvalidResponse = errors.New("openwa: invalid API response")
ErrResponseTooLarge = errors.New("openwa: response exceeds configured limit")
ErrRequestTooLarge = errors.New("openwa: request exceeds configured limit")
ErrDocumentTooLarge = errors.New("openwa: document exceeds configured limit")
ErrRedirect = errors.New("openwa: redirects are disabled")
// ErrOutcomeUnknown means that a send may have taken effect. Persist and
// reconcile the attempt instead of blindly resending it.
ErrOutcomeUnknown = errors.New("openwa: send outcome is unknown")
)
// APIError contains bounded metadata from an unsuccessful HTTP response.
// Code is untrusted upstream data; do not log it without sanitization.
// Error deliberately omits the upstream body, message, code, URL and credentials.
type APIError struct {
StatusCode int
Code string
RetryAfter string
}
func (e *APIError) Error() string {
return fmt.Sprintf("openwa: API returned HTTP %d", e.StatusCode)
}
// SendError wraps an ambiguous result after dispatch. errors.Is with
// ErrOutcomeUnknown identifies it; errors.As still exposes an underlying APIError.
type SendError struct{ cause error }
func (e *SendError) Error() string { return ErrOutcomeUnknown.Error() }
func (e *SendError) Unwrap() error { return e.cause }
func (e *SendError) Is(target error) bool { return target == ErrOutcomeUnknown }
// transportError preserves errors.Is/As for cancellation and network errors,
// while avoiding net/http's URL-bearing error message in the default string.
type transportError struct{ cause error }
func (e *transportError) Error() string { return ErrTransport.Error() }
func (e *transportError) Unwrap() error { return e.cause }
func (e *transportError) Is(target error) bool { return target == ErrTransport }
func sendError(err error, dispatched bool) error {
if err == nil || !dispatched {
return err
}
var apiErr *APIError
if errors.As(err, &apiErr) && apiErr.StatusCode >= 400 && apiErr.StatusCode < 500 && apiErr.StatusCode != 408 {
return err
}
return &SendError{cause: err}
}