papers_openalex/error.rs
1/// Errors returned by [`OpenAlexClient`](crate::OpenAlexClient) methods.
2///
3/// # Variants
4///
5/// - [`Http`](OpenAlexError::Http) — network or connection failure (wraps
6/// [`reqwest::Error`])
7/// - [`Json`](OpenAlexError::Json) — response body could not be deserialized
8/// (wraps [`serde_json::Error`])
9/// - [`Api`](OpenAlexError::Api) — the OpenAlex API returned a non-success HTTP
10/// status code (e.g. 404 for unknown entity, 403 for forbidden, 500 for
11/// server error)
12///
13/// # Example
14///
15/// ```no_run
16/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
17/// use papers_openalex::{OpenAlexClient, GetParams, OpenAlexError};
18///
19/// let client = OpenAlexClient::new();
20/// match client.get_work("nonexistent", &GetParams::default()).await {
21/// Ok(work) => println!("Found: {}", work.id),
22/// Err(OpenAlexError::Api { status, message }) => {
23/// eprintln!("API error {status}: {message}");
24/// }
25/// Err(e) => eprintln!("Other error: {e}"),
26/// }
27/// # Ok(())
28/// # }
29/// ```
30#[derive(Debug, thiserror::Error)]
31pub enum OpenAlexError {
32 /// Network or connection error from reqwest.
33 #[error("HTTP error: {0}")]
34 Http(#[from] reqwest::Error),
35
36 /// Failed to deserialize the JSON response body.
37 #[error("JSON error: {0}")]
38 Json(#[from] serde_json::Error),
39
40 /// The API returned a non-success HTTP status code.
41 ///
42 /// `status` is the HTTP status code (e.g. 404, 403, 500) and `message`
43 /// contains the response body text.
44 #[error("API error (status {status}): {message}")]
45 Api { status: u16, message: String },
46}
47
48/// A [`Result`](std::result::Result) alias with [`OpenAlexError`] as the error
49/// type.
50pub type Result<T> = std::result::Result<T, OpenAlexError>;