Skip to main content

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>;