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
142
143
144
145
146
147
148
149
150
//! Typed error enums for the `victauri-plugin` crate.
/// Errors that can occur when building the Victauri plugin via [`crate::VictauriBuilder`].
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum BuilderError {
/// The configured port is invalid (e.g., port 0).
#[error("invalid port {port}: {reason}")]
InvalidPort {
/// The invalid port number.
port: u16,
/// Why the port is invalid.
reason: String,
},
/// The event log capacity is out of the valid range.
#[error("invalid event capacity {capacity}: {reason}")]
InvalidEventCapacity {
/// The invalid capacity value.
capacity: usize,
/// Why the capacity is invalid.
reason: String,
},
/// The recorder capacity is out of the valid range.
#[error("invalid recorder capacity {capacity}: {reason}")]
InvalidRecorderCapacity {
/// The invalid capacity value.
capacity: usize,
/// Why the capacity is invalid.
reason: String,
},
/// The eval timeout is out of the valid range.
#[error("invalid eval timeout {timeout_secs}s: {reason}")]
InvalidEvalTimeout {
/// The invalid timeout in seconds.
timeout_secs: u64,
/// Why the timeout is invalid.
reason: String,
},
}
/// Errors that can occur during MCP server operation, tool execution, or webview interaction.
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum PluginError {
/// A JavaScript eval timed out waiting for a response from the webview.
#[error("eval timed out after {timeout_secs}s")]
EvalTimeout {
/// How many seconds elapsed before the timeout.
timeout_secs: u64,
},
/// A JavaScript eval returned an error from the webview.
#[error("eval failed: {message}")]
EvalFailed {
/// The error message from the webview.
message: String,
},
/// Too many concurrent eval requests are pending.
#[error("too many concurrent eval requests (limit: {limit})")]
EvalConcurrencyExceeded {
/// The maximum number of concurrent eval requests.
limit: usize,
},
/// The webview bridge returned an error.
#[error("bridge error: {message}")]
BridgeError {
/// The error message from the bridge.
message: String,
},
/// Screenshot capture failed.
#[error("screenshot failed: {message}")]
ScreenshotFailed {
/// The error message from the screenshot subsystem.
message: String,
},
/// Bearer-token authentication failed.
#[error("authentication failed: {message}")]
AuthenticationFailed {
/// The error message describing the auth failure.
message: String,
},
/// The rate limiter rejected the request.
#[error("rate limit exceeded")]
RateLimitExceeded,
/// The requested tool is disabled by the privacy configuration.
#[error("tool '{tool_name}' is disabled by privacy configuration")]
ToolDisabled {
/// Name of the disabled tool.
tool_name: String,
},
/// The requested command is blocked by the privacy configuration.
#[error("command '{command}' is blocked by privacy configuration")]
CommandBlocked {
/// Name of the blocked command.
command: String,
},
/// No window with the given label was found.
#[error("window not found: {label}")]
WindowNotFound {
/// The window label that was not found.
label: String,
},
/// The MCP server failed to start (e.g., all ports in use).
#[error("MCP server failed to start: {message}")]
ServerStartFailed {
/// The error message from the server startup.
message: String,
},
/// The configured port is already bound by another process.
#[error("port {port} is already in use")]
PortInUse {
/// The port that is already in use.
port: u16,
},
/// JSON serialization or deserialization failed.
#[error("serialization error: {0}")]
Serialization(#[from] serde_json::Error),
/// An I/O operation failed.
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
/// A URL failed validation.
#[error("invalid URL: {message}")]
InvalidUrl {
/// The error message describing why the URL is invalid.
message: String,
},
/// An error propagated from the `victauri-core` crate.
#[error(transparent)]
Core(#[from] victauri_core::VictauriError),
}
/// Convenience alias for `std::result::Result<T, PluginError>`.
pub type Result<T> = std::result::Result<T, PluginError>;