opencode_codes/error.rs
1//! Error types for the opencode-codes crate.
2//!
3//! All fallible operations return [`Result<T>`], which uses [`enum@Error`] as the
4//! error type. The core variants ([`Error::Http`], [`Error::Serde`]) are
5//! available in the `types` tier and build on `wasm32`. Transport, SSE, and
6//! server-lifecycle variants are gated behind the features whose dependencies
7//! supply their source types.
8
9use thiserror::Error;
10
11/// Error type for the opencode-codes crate.
12#[derive(Debug, Error)]
13pub enum Error {
14 /// The opencode server returned a non-success HTTP status.
15 ///
16 /// `status` is the HTTP status code; `body` is the (best-effort) response
17 /// body, useful for surfacing the server's error payload.
18 #[error("HTTP {status}: {body}")]
19 Http {
20 /// HTTP status code returned by the server.
21 status: u16,
22 /// Response body, captured for diagnostics.
23 body: String,
24 },
25
26 /// JSON serialization or deserialization failed.
27 ///
28 /// Returned when request bodies can't be serialized or response/SSE
29 /// payloads don't match the expected shape.
30 #[error("JSON error: {0}")]
31 Serde(#[from] serde_json::Error),
32
33 /// A transport-level error occurred while talking to the server.
34 ///
35 /// Common causes: connection refused, TLS failure, timeout, broken pipe.
36 ///
37 /// Boxed because `reqwest::Error` embeds a `reqwest::Response` and is large;
38 /// boxing keeps the whole [`enum@Error`] small enough that `-> Result<T>`
39 /// does not trip `clippy::result_large_err`.
40 #[cfg(feature = "async-client")]
41 #[error("transport error: {0}")]
42 Transport(Box<reqwest::Error>),
43
44 /// The Server-Sent Events stream failed.
45 ///
46 /// Returned when the `GET /event` stream errors, closes unexpectedly, or
47 /// yields a frame that cannot be decoded.
48 ///
49 /// Boxed for the same size reason as [`Error::Transport`].
50 #[cfg(feature = "async-client")]
51 #[error("SSE error: {0}")]
52 Sse(Box<reqwest_eventsource::Error>),
53
54 /// The managed `opencode serve` process could not be spawned or exited
55 /// unexpectedly.
56 #[cfg(feature = "server")]
57 #[error("server lifecycle error: {0}")]
58 Server(String),
59}
60
61#[cfg(feature = "async-client")]
62impl From<reqwest::Error> for Error {
63 fn from(err: reqwest::Error) -> Self {
64 Error::Transport(Box::new(err))
65 }
66}
67
68#[cfg(feature = "async-client")]
69impl From<reqwest_eventsource::Error> for Error {
70 fn from(err: reqwest_eventsource::Error) -> Self {
71 Error::Sse(Box::new(err))
72 }
73}
74
75/// A `Result` type alias using [`enum@Error`].
76pub type Result<T> = std::result::Result<T, Error>;