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