Skip to main content

typesafe_jev/
error.rs

1use std::fmt;
2
3/// Why a client could not be built, or a request could not be answered.
4///
5/// Transient failures (connection errors, HTTP 429, 5xx) are retried inside
6/// [`Client::ask`](crate::Client::ask) and only surface as [`Error::Api`] once the retries are
7/// spent. The other variants are returned at once, because retrying cannot help.
8///
9/// The enum is `#[non_exhaustive]`: a later version may tell more failures apart, so a `match`
10/// needs a wildcard arm. [`Error::message`] and `Display` give the text of any variant.
11#[derive(Debug, Clone, PartialEq, Eq)]
12#[non_exhaustive]
13pub enum Error {
14    /// Missing, blank, unsendable or rejected credentials (HTTP 401 or 403).
15    Auth(String),
16    /// The request exceeded the model's context (`max_tokens_exceeded`, or HTTP 413). Ask fewer
17    /// questions, or about less state, and retry.
18    TokenLimit(String),
19    /// A [`Config`](crate::Config) no request could be sent with: a base URL that is not an
20    /// absolute `http` or `https` URL, or a user agent that is not a valid header value.
21    /// Reported by [`Client::new`](crate::Client::new), before anything is sent.
22    InvalidConfig(String),
23    /// Anything else: an unreadable response, an unexpected status, or retries exhausted.
24    Api(String),
25}
26
27impl Error {
28    /// The message, without the variant.
29    pub fn message(&self) -> &str {
30        let (Error::Auth(m) | Error::TokenLimit(m) | Error::InvalidConfig(m) | Error::Api(m)) = self;
31        m
32    }
33}
34
35impl fmt::Display for Error {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        f.write_str(self.message())
38    }
39}
40
41impl std::error::Error for Error {}