notion_sdk/
error.rs

1//!
2//! # Notion Error
3//!
4use crate::pagination::Object;
5use serde::{Deserialize, Serialize};
6use std::fmt::{Debug, Display, Formatter};
7use std::num::NonZeroU16;
8
9/// An wrapper Error type for all errors produced by the NotionApi client.
10#[derive(Debug, thiserror::Error)]
11pub enum Error {
12    #[error("Invalid UUID: {}", source)]
13    UUID { source: uuid::Error },
14
15    #[error("Invalid Notion API Token: {}", source)]
16    InvalidApiToken {
17        source: reqwest::header::InvalidHeaderValue,
18    },
19
20    #[error("Unable to build reqwest HTTP client: {}", source)]
21    ErrorBuildingClient { source: reqwest::Error },
22
23    #[error("Error sending HTTP request: {}", source)]
24    RequestFailed {
25        #[from]
26        source: reqwest::Error,
27    },
28
29    #[error("Error reading response: {}", source)]
30    ResponseIoError { source: reqwest::Error },
31
32    #[error("Error parsing json response: {}", source)]
33    JsonParseError { source: serde_json::Error },
34
35    #[error("Unexpected API Response")]
36    UnexpectedResponse { response: Object },
37
38    #[error("API Error {}({}): {}", .error.code, .error.status, .error.message)]
39    ApiError { error: ErrorResponse },
40}
41
42#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
43#[serde(transparent)]
44pub struct StatusCode(NonZeroU16);
45
46impl Display for StatusCode {
47    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
48        write!(f, "{}", self.0)
49    }
50}
51
52/// <https://developers.notion.com/reference/errors>
53#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)]
54pub struct ErrorResponse {
55    pub status: StatusCode,
56    pub code: ErrorCode,
57    pub message: String,
58}
59
60/// <https://developers.notion.com/reference/errors>
61#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)]
62#[serde(rename_all = "snake_case")]
63pub enum ErrorCode {
64    /// The request body could not be decoded as JSON.
65    InvalidJson,
66    /// The request URL is not valid.
67    InvalidRequestUrl,
68    /// This request is not supported.
69    InvalidRequest,
70    /// The request body does not match the schema for the expected parameters. Check the "message" property for more details.
71    ValidationError,
72    /// The request is missing the required Notion-Version header. See Versioning.
73    MissionVersion,
74    /// The bearer token is not valid.
75    Unauthorized,
76    /// Given the bearer token used, the client doesn't have permission to perform this operation.
77    RestrictedResource,
78    /// Given the bearer token used, the resource does not exist. This error can also indicate that the resource has not been shared with owner of the bearer token.
79    ObjectNotFound,
80    /// The transaction could not be completed, potentially due to a data collision. Make sure the parameters are up to date and try again.
81    ConflictError,
82    /// This request exceeds the number of requests allowed. Slow down and try again. More details on rate limits.
83    RateLimited,
84    /// An unexpected error occurred. Reach out to Notion support.
85    InternalServerError,
86    /// Notion is unavailable. Try again later. This can occur when the time to respond to a request takes longer than 60 seconds, the maximum request timeout.
87    ServiceUnavailable,
88    /// Notion's database is unavailable or in an unqueryable state. Try again later.
89    DatabaseConnectionUnavailable,
90    #[serde(other)] // serde issue #912
91    Unknown,
92}
93
94impl Display for ErrorCode {
95    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
96        write!(f, "{self:?}")
97    }
98}