Skip to main content

llmleaf_client/
error.rs

1//! The SDK's typed error.
2
3use serde::Deserialize;
4
5/// Errors returned by the SDK.
6///
7/// [`Error::Api`] is the structured gateway error parsed from the canonical
8/// `{"error":{"message":"..."}}` envelope (see SPEC.md). Everything else is a
9/// transport or decoding failure.
10#[derive(Debug, thiserror::Error)]
11#[non_exhaustive]
12pub enum Error {
13    /// A non-2xx response from the gateway, carrying its HTTP status and the
14    /// `error.message` field from the envelope.
15    ///
16    /// Status codes (per SPEC.md): 400 bad request · 401 missing/invalid key ·
17    /// 403 blocked or model-not-allowed · 404 no route for model ·
18    /// 429 key suspended (limiter) · 502 all upstreams failed.
19    #[error("api error {status}: {message}")]
20    Api {
21        /// HTTP status code of the failed response.
22        status: u16,
23        /// Human-readable message from `error.message`.
24        message: String,
25    },
26
27    /// The configured base URL could not be parsed.
28    #[error("invalid base url: {0}")]
29    InvalidBaseUrl(String),
30
31    /// An HTTP / transport-level failure (connection, TLS, timeout, …).
32    #[error("http transport error: {0}")]
33    Http(#[from] reqwest::Error),
34
35    /// A JSON body could not be (de)serialised.
36    #[error("json error: {0}")]
37    Json(#[from] serde_json::Error),
38
39    /// A base64 embedding payload could not be decoded.
40    #[error("base64 decode error: {0}")]
41    Base64(#[from] base64::DecodeError),
42
43    /// The server sent a malformed SSE / NDJSON stream.
44    #[error("malformed stream: {0}")]
45    Stream(String),
46}
47
48/// The on-the-wire error envelope: `{"error":{"message":"..."}}`.
49#[derive(Debug, Deserialize)]
50pub(crate) struct ErrorEnvelope {
51    pub error: ErrorBody,
52}
53
54#[derive(Debug, Deserialize)]
55pub(crate) struct ErrorBody {
56    #[serde(default)]
57    pub message: String,
58    #[allow(dead_code)]
59    #[serde(default)]
60    pub r#type: Option<String>,
61    #[allow(dead_code)]
62    #[serde(default)]
63    pub code: Option<String>,
64}
65
66/// A convenience result alias.
67pub type Result<T> = std::result::Result<T, Error>;