-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy patherror_mapping.go
More file actions
97 lines (90 loc) · 3.26 KB
/
Copy patherror_mapping.go
File metadata and controls
97 lines (90 loc) · 3.26 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
package e2b
import (
"context"
"errors"
"net/http"
"strings"
"connectrpc.com/connect"
"github.com/eric642/e2b-go-sdk/internal/transport"
)
// mapConnectErr translates a Connect-RPC error into one of the SDK error
// types. Fallback is *SandboxError.
func mapConnectErr(err error) error {
if err == nil {
return nil
}
if ctxErr := contextErr(err); ctxErr != nil {
return ctxErr
}
var ce *connect.Error
if !errors.As(err, &ce) {
return newSandboxError(err.Error(), err)
}
msg := ce.Message()
switch ce.Code() {
case connect.CodeInvalidArgument:
return &InvalidArgumentError{Message: msg}
case connect.CodeUnauthenticated, connect.CodePermissionDenied:
return &AuthenticationError{Message: msg}
case connect.CodeNotFound:
return &FileNotFoundError{Message: msg}
case connect.CodeResourceExhausted:
// envd returns ResourceExhausted for out-of-space and rate limit.
// Disk-full messages usually contain "no space" — treat those as
// NotEnoughSpaceError for parity with JS/Python.
if strings.Contains(strings.ToLower(msg), "no space") {
return &NotEnoughSpaceError{Message: msg}
}
return &RateLimitError{Message: msg}
case connect.CodeUnavailable, connect.CodeCanceled, connect.CodeDeadlineExceeded:
return &TimeoutError{Message: msg, Cause: err}
}
return newSandboxError(msg, err)
}
// mapHTTPErr translates an unexpected HTTP response into an SDK error. The
// resp body is consumed via transport.ReadHTTPError. sandboxID optionally
// annotates SandboxNotFoundError when mapping 404 from a sandbox endpoint.
func mapHTTPErr(resp *http.Response, sandboxID string) error {
if resp == nil {
return newSandboxError("empty response", nil)
}
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
return nil
}
httpErr := transport.ReadHTTPError(resp)
switch resp.StatusCode {
case http.StatusUnauthorized, http.StatusForbidden:
return &AuthenticationError{Message: httpErr.Message}
case http.StatusNotFound:
if sandboxID != "" {
return &SandboxNotFoundError{SandboxID: sandboxID, Message: httpErr.Message}
}
return &NotFoundError{Message: httpErr.Message}
case http.StatusTooManyRequests:
return &RateLimitError{Message: httpErr.Message}
case http.StatusInsufficientStorage:
return &NotEnoughSpaceError{Message: httpErr.Message}
case http.StatusRequestTimeout, http.StatusGatewayTimeout:
return &TimeoutError{Message: httpErr.Message}
}
return newSandboxError(httpErr.Error(), nil)
}
// mapEnvdFileErr translates an unexpected response from envd's /files HTTP
// endpoint into an SDK error. Unlike mapHTTPErr it maps 404 to
// *FileNotFoundError (file semantics), matching the Connect-RPC filesystem path
// (mapConnectErr) so callers can detect a missing file uniformly regardless of
// transport. Other statuses defer to mapHTTPErr.
func mapEnvdFileErr(resp *http.Response, path string) error {
if resp != nil && resp.StatusCode == http.StatusNotFound {
httpErr := transport.ReadHTTPError(resp)
return &FileNotFoundError{Path: path, Message: httpErr.Message}
}
return mapHTTPErr(resp, "")
}
// contextErr wraps context timeouts into TimeoutError.
func contextErr(err error) error {
if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
return &TimeoutError{Message: err.Error(), Cause: err}
}
return nil
}