-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherrors.go
More file actions
131 lines (110 loc) · 3.98 KB
/
errors.go
File metadata and controls
131 lines (110 loc) · 3.98 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
package w3pilot
import (
"errors"
"fmt"
"strings"
)
var (
// ErrConnectionFailed is returned when WebSocket connection fails.
ErrConnectionFailed = errors.New("failed to connect to browser")
// ErrElementNotFound is returned when an element cannot be found.
ErrElementNotFound = errors.New("element not found")
// ErrBrowserCrashed is returned when the browser process exits unexpectedly.
ErrBrowserCrashed = errors.New("browser crashed")
// ErrBrowserNotFound is returned when Chrome cannot be found.
ErrBrowserNotFound = errors.New("Chrome not found")
// ErrClickerNotFound is deprecated: use ErrBrowserNotFound instead.
// Deprecated: This error is no longer used. Use ErrBrowserNotFound.
ErrClickerNotFound = ErrBrowserNotFound
// ErrTimeout is returned when an operation times out.
ErrTimeout = errors.New("operation timed out")
// ErrConnectionClosed is returned when the WebSocket connection is closed.
ErrConnectionClosed = errors.New("connection closed")
)
// PageContext provides context about the page state when an error occurred.
// This helps AI agents understand the situation and recover from errors.
type PageContext struct {
URL string `json:"url"`
Title string `json:"title"`
VisibleText string `json:"visible_text,omitempty"`
}
// ConnectionError represents a WebSocket connection failure.
type ConnectionError struct {
URL string
Cause error
}
func (e *ConnectionError) Error() string {
if e.Cause != nil {
return fmt.Sprintf("failed to connect to %s: %v", e.URL, e.Cause)
}
return fmt.Sprintf("failed to connect to %s", e.URL)
}
func (e *ConnectionError) Unwrap() error {
return e.Cause
}
// TimeoutError represents a timeout waiting for an element or action.
type TimeoutError struct {
Selector string `json:"selector"`
Timeout int64 `json:"timeout_ms"` // milliseconds
Reason string `json:"reason,omitempty"`
PageContext *PageContext `json:"page_context,omitempty"`
Suggestions []string `json:"suggestions,omitempty"`
}
func (e *TimeoutError) Error() string {
if e.Reason != "" {
return fmt.Sprintf("timeout after %dms waiting for '%s': %s", e.Timeout, e.Selector, e.Reason)
}
return fmt.Sprintf("timeout after %dms waiting for '%s'", e.Timeout, e.Selector)
}
// ElementNotFoundError represents an element that could not be found.
type ElementNotFoundError struct {
Selector string `json:"selector"`
PageContext *PageContext `json:"page_context,omitempty"`
Suggestions []string `json:"suggestions,omitempty"`
}
func (e *ElementNotFoundError) Error() string {
return fmt.Sprintf("element not found: %s", e.Selector)
}
// BrowserCrashedError represents an unexpected browser exit.
type BrowserCrashedError struct {
ExitCode int
Output string
}
func (e *BrowserCrashedError) Error() string {
if e.Output != "" {
return fmt.Sprintf("browser crashed with exit code %d: %s", e.ExitCode, e.Output)
}
return fmt.Sprintf("browser crashed with exit code %d", e.ExitCode)
}
// BiDiError represents an error from the BiDi protocol.
type BiDiError struct {
ErrorType string
Message string
}
func (e *BiDiError) Error() string {
if e.Message != "" {
return fmt.Sprintf("%s: %s", e.ErrorType, e.Message)
}
return e.ErrorType
}
// IsUnsupportedCommand returns true if the error indicates the command is not
// supported by the backend (e.g., clicker doesn't implement a vibium: command).
// This is used internally to trigger fallback to CDP.
func IsUnsupportedCommand(err error) bool {
if err == nil {
return false
}
var bidiErr *BiDiError
if errors.As(err, &bidiErr) {
// Check for common "unknown command" error patterns
switch bidiErr.ErrorType {
case "unknown command", "unknown method", "invalid method", "not implemented":
return true
}
}
// Also check error message for common patterns (case-insensitive)
errMsg := strings.ToLower(err.Error())
return strings.Contains(errMsg, "unknown command") ||
strings.Contains(errMsg, "unknown method") ||
strings.Contains(errMsg, "not implemented")
}