supabase_auth/
error.rs

1/*!
2Provides error types and handling for Supabase authentication operations.
3
4This module defines the primary [`Error`] enum and supporting types for handling various
5error conditions that may occur during authentication operations.
6
7The most common error is [`Error::Supabase`] which wraps [`SupabaseHTTPError`]. This is a transparent error which gives you the `status` as a [`StatusCode`] and `message` from the Supabase response.
8*/
9
10use std::{
11    env,
12    fmt::{self, Display},
13};
14
15use reqwest::StatusCode;
16use serde::{Deserialize, Serialize};
17use thiserror::Error;
18
19#[derive(Debug, Error)]
20pub enum Error {
21    #[error("User Already Exists")]
22    AlreadySignedUp,
23    #[error("Invalid Credentials")]
24    WrongCredentials,
25    #[error("User Not Found")]
26    UserNotFound,
27    #[error("Supabase Client not Authenticated")]
28    NotAuthenticated,
29    #[error("Missing Refresh Token")]
30    MissingRefreshToken,
31    #[error("JWT Is Invalid")]
32    WrongToken,
33    #[error("Internal Error")]
34    InternalError,
35    #[error("Network Error")]
36    NetworkError(#[from] reqwest::Error),
37    #[error("Failed to Parse")]
38    ParseError(#[from] serde_json::Error),
39    #[error("Header Value is Invalid")]
40    InvalidHeaderValue(#[from] reqwest::header::InvalidHeaderValue),
41    #[error("Environment Variable Unreadable")]
42    InvalidEnvironmentVariable(#[from] env::VarError),
43    #[error("Failed to parse URL")]
44    ParseUrlError,
45    #[error("{0}")]
46    Supabase(SupabaseHTTPError),
47    #[error("Error: {status}: {message}")]
48    AuthError { status: StatusCode, message: String },
49}
50
51#[derive(Debug, Serialize, Deserialize)]
52pub struct SupabaseHTTPError {
53    pub code: i32,
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub error_code: Option<String>,
56    #[serde(rename = "msg")]
57    pub message: String,
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub internal_error: Option<serde_json::Value>,
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub internal_message: Option<serde_json::Value>,
62    #[serde(skip_serializing_if = "Option::is_none")]
63    pub error_id: Option<String>,
64}
65
66impl Display for SupabaseHTTPError {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
68        write!(f, "Status Code {}", self.code)?;
69
70        if let Some(error_code) = &self.error_code {
71            write!(f, " ({})", error_code)?;
72        }
73
74        if let Some(error_id) = &self.error_id {
75            write!(f, " [Error ID: {}]", error_id)?;
76        }
77
78        if let Some(internal_message) = &self.internal_message {
79            write!(f, "\nInternal message: {}", internal_message)?;
80        }
81
82        if let Some(internal_error) = &self.internal_error {
83            write!(f, "\nInternal error: {}", internal_error)?;
84        }
85
86        write!(f, "\nMessage: {}", self.message)
87    }
88}