Authkestra

Error Handling

Authkestra uses the AuthError enum for all authentication-related errors.

Authkestra uses the AuthError enum for all authentication-related errors, providing type-safe error handling throughout your application.

AuthError Enum

authkestra-core/src/error.rs
use thiserror::Error;

/// Errors that can occur during the authentication process.
#[derive(Debug, thiserror::Error)]
pub enum AuthError {
    /// An error returned by the authentication provider
    #[error("Provider error: {0}")]
    Provider(String),
    /// The provided credentials (email/password) are invalid
    #[error("Invalid credentials")]
    InvalidCredentials,
    /// The authorization code is invalid or expired
    #[error("Invalid code")]
    InvalidCode,
    /// A network error occurred during communication with the provider
    #[error("Network error")]
    Network,
    /// An error occurred during session management
    #[error("Session error: {0}")]
    Session(String),
    /// An error occurred during token processing
    #[error("Token error: {0}")]
    Token(String),
    /// The CSRF state parameter does not match the expected value
    #[error("CSRF state mismatch")]
    CsrfMismatch,
    /// An error occurred during OIDC discovery
    #[error("Discovery error: {0}")]
    Discovery(String),
}

Error Variants

VariantWhen It OccursHTTP Status
ProviderAn error returned by the authentication provider502 Bad Gateway
InvalidCredentialsThe provided credentials (email/password) are invalid401 Unauthorized
InvalidCodeThe authorization code is invalid or expired400 Bad Request
NetworkA network error occurred during communication with the provider503 Service Unavailable
SessionAn error occurred during session management401 Unauthorized
TokenAn error occurred during token processing401 Unauthorized
CsrfMismatchThe CSRF state parameter does not match the expected value400 Bad Request
DiscoveryAn error occurred during OIDC discovery502 Bad Gateway

Handling Errors

Use Rust's pattern matching to handle specific error cases:

example.rs
use authkestra_core::AuthError;

async fn login(creds: LoginCredentials) -> Result<Response, AppError> {
    match auth.authenticate(creds).await {
        Ok(session) => Ok(create_session_response(session)),
        
        Err(AuthError::InvalidCredentials) => {
            // Log failed attempt, maybe rate limit
            Ok(Response::unauthorized("Invalid username or password"))
        }
        
        Err(AuthError::Provider(msg)) => {
            // Log provider error
            tracing::error!("Auth provider error: {}", msg);
            Err(AppError::ProviderError)
        }
        
        Err(e) => {
            // Handle other errors
            Ok(Response::bad_request(e.to_string()))
        }
    }
}

Custom Error Responses

Implement IntoResponse to customize how errors are returned to clients:

example.rs
use axum::{
    http::StatusCode,
    response::{IntoResponse, Response},
    Json,
};
use authkestra_core::AuthError;
use serde_json::json;

impl IntoResponse for AuthError {
    fn into_response(self) -> Response {
        let (status, message) = match &self {
            AuthError::InvalidCredentials => {
                (StatusCode::UNAUTHORIZED, "Invalid credentials")
            }
            AuthError::Session(_) => {
                (StatusCode::UNAUTHORIZED, "Session invalid or expired")
            }
            AuthError::Token(_) => {
                (StatusCode::UNAUTHORIZED, "Token invalid or expired")
            }
            AuthError::CsrfMismatch | AuthError::InvalidCode => {
                (StatusCode::BAD_REQUEST, "Authentication failed")
            }
            AuthError::Provider(_) | AuthError::Discovery(_) => {
                (StatusCode::BAD_GATEWAY, "Provider error")
            }
            AuthError::Network => {
                (StatusCode::SERVICE_UNAVAILABLE, "Network error")
            }
        };

        let body = Json(json!({
            "error": message,
            "code": status.as_u16()
        }));

        (status, body).into_response()
    }
}

Error Logging

Always log internal errors with context before returning them. Use a logging framework like tracing to capture error details for debugging.

On this page