openfga_client/
error.rs

1use std::sync::Arc;
2
3use tonic::codegen::StdError;
4
5use crate::generated::ReadRequestTupleKey;
6
7pub type Result<T> = std::result::Result<T, Error>;
8
9#[derive(Debug, thiserror::Error, Clone)]
10pub enum Error {
11    #[error("Multiple stores with the name `{0}` found")]
12    AmbiguousStoreName(String),
13    #[error("Request to OpenFGA failed with status: {0}")]
14    RequestFailed(Box<tonic::Status>),
15    #[error(
16        "Too many pages returned for read request tuple key {}. Max pages: {max_pages}",
17        tuple.as_ref().map_or_else(|| "<No tuple key provided>".to_string(), |t| format!("{t}"))
18    )]
19    TooManyPages {
20        max_pages: u32,
21        tuple: Option<ReadRequestTupleKey>,
22    },
23    #[error("Invalid Endpoint: `{0}`")]
24    InvalidEndpoint(String),
25    #[error("Invalid Token: {reason}")]
26    InvalidToken { reason: String },
27    #[cfg(feature = "auth-middle")]
28    #[error("Failed to fetch or refresh Client Credentials: {0}")]
29    CredentialRefreshError(#[source] middle::Error),
30    #[error(
31        "Invalid OpenFGA Model Version: `{0}`. Model Versions must have the format `major.minor`"
32    )]
33    InvalidModelVersion(String),
34    #[error("Migration Hook for model version {version} failed: {error}")]
35    MigrationHookFailed {
36        version: String,
37        error: Arc<StdError>,
38    },
39    #[error("Missing authorization model id for model prefix `{model_prefix}` version `{version}`")]
40    MissingAuthorizationModelId {
41        model_prefix: String,
42        version: String,
43    },
44    #[error("Store with Name `{0}` not found")]
45    StoreNotFound(String),
46    #[error(
47        "Multiple authorization models with model prefix `{model_prefix}` for version `{version}` found."
48    )]
49    AmbiguousModelVersion {
50        model_prefix: String,
51        version: String,
52    },
53    #[error(
54        "Too many writes and deletes in single OpenFGA transaction (actual) {actual} > {max} (max)"
55    )]
56    TooManyWrites { actual: i32, max: i32 },
57    /// Protobuf `oneof` fields are always wrapped in an `Option` by `prost` ([ref]).
58    /// `ExpectedOneof` is raised if OpenFGA is expected to return one of the variants
59    /// (i.e. `Some(T)`) but instead `None` was received.
60    ///
61    /// [ref]: https://github.com/tokio-rs/prost?tab=readme-ov-file#oneof-fields
62    #[error("Expected Oneof variant but got None")]
63    ExpectedOneof,
64    #[error("TLS configuration failed for endpoint `{endpoint}`: {reason}")]
65    TlsConfigurationFailed { endpoint: String, reason: String },
66}
67
68impl Error {
69    // pub fn internal(
70    //     reason: impl Into<String>,
71    //     error: impl Into<Box<dyn std::error::Error + Send + Sync>>,
72    // ) -> Self {
73    //     Self::InternalError {
74    //         reason: reason.into(),
75    //         source: error.into(),
76    //     }
77    // }
78}