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 request the API would not evaluate: a state that does not serialize to JSON, or a body
20 /// the API refused as malformed (HTTP 422), such as a [`Score`](crate::Score) with a single
21 /// level or a state that is a bare number. The message quotes what the API objected to.
22 InvalidRequest(String),
23 /// A [`Config`](crate::Config) no request could be sent with: a base URL that is not an
24 /// absolute `http` or `https` URL, or a user agent that is not a valid header value.
25 /// Reported by [`Client::new`](crate::Client::new), before anything is sent.
26 InvalidConfig(String),
27 /// Anything else: an unreadable response, an unexpected status, or retries exhausted.
28 Api(String),
29}
30
31impl Error {
32 /// The message, without the variant.
33 pub fn message(&self) -> &str {
34 let (Error::Auth(m) | Error::TokenLimit(m) | Error::InvalidRequest(m) | Error::InvalidConfig(m) | Error::Api(m)) = self;
35 m
36 }
37}
38
39impl fmt::Display for Error {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 f.write_str(self.message())
42 }
43}
44
45impl std::error::Error for Error {}