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(
40        "Missing authorization model id for model prefix `{model_prefix}` version `{version}`"
41    )]
42    MissingAuthorizationModelId {
43        model_prefix: String,
44        version: String,
45    },
46    #[error("Store with Name `{0}` not found")]
47    StoreNotFound(String),
48    #[error("Multiple authorization models with model prefix `{model_prefix}` for version `{version}` found.")]
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}
65
66impl Error {
67    // pub fn internal(
68    //     reason: impl Into<String>,
69    //     error: impl Into<Box<dyn std::error::Error + Send + Sync>>,
70    // ) -> Self {
71    //     Self::InternalError {
72    //         reason: reason.into(),
73    //         source: error.into(),
74    //     }
75    // }
76}