langdb_core 0.3.2

AI gateway Core for LangDB AI Gateway.
Documentation
#[cfg(feature = "database")]
pub mod database;
pub mod embed_mod;
pub mod error;
pub mod events;
pub mod executor;
pub mod handler;
pub mod http;
pub mod llm_gateway;
pub mod model;
pub mod models;
pub mod pricing;
pub mod responses;
pub mod routing;
pub mod telemetry;
pub mod types;

use crate::error::GatewayError;
use crate::types::gateway::CostCalculatorError;
use actix_web::http::header::ContentType;
use actix_web::http::StatusCode;
use actix_web::HttpResponse;
use executor::chat_completion::routed_executor::RoutedExecutorError;
use serde_json::json;
use thiserror::Error;

pub use dashmap;

pub mod usage;

pub use bytes;
use types::guardrails::GuardError;

pub type GatewayResult<T> = Result<T, GatewayError>;

pub use either;
pub use rmcp;

#[derive(Error, Debug)]
pub enum GatewayApiError {
    #[error("Failed to parse JSON")]
    JsonParseError(#[from] serde_json::Error),

    #[error(transparent)]
    GatewayError(#[from] GatewayError),

    #[error("{0}")]
    CustomError(String),

    #[error(transparent)]
    CostCalculatorError(#[from] CostCalculatorError),

    #[error("Token usage limit exceeded")]
    TokenUsageLimit,

    #[error(transparent)]
    RouteError(#[from] routing::RouterError),

    #[error(transparent)]
    RoutedExecutorError(#[from] RoutedExecutorError),
}

impl GatewayApiError {
    pub fn is_countable_error(&self) -> bool {
        !matches!(
            self,
            GatewayApiError::GatewayError(GatewayError::GuardError(GuardError::GuardNotPassed(
                _,
                _
            )))
        )
    }
}

impl actix_web::error::ResponseError for GatewayApiError {
    fn error_response(&self) -> HttpResponse {
        tracing::error!("API error: {:?}", self);
        match self {
            GatewayApiError::GatewayError(e) => e.error_response(),
            e => {
                let json_error = json!({
                    "error": e.to_string(),
                });

                HttpResponse::build(e.status_code())
                    .insert_header(ContentType::json())
                    .json(json_error)
            }
        }
    }

    fn status_code(&self) -> StatusCode {
        match self {
            GatewayApiError::JsonParseError(_) => StatusCode::BAD_REQUEST,
            GatewayApiError::GatewayError(e) => e.status_code(),
            GatewayApiError::CustomError(_) => StatusCode::INTERNAL_SERVER_ERROR,
            GatewayApiError::CostCalculatorError(_) => StatusCode::INTERNAL_SERVER_ERROR,
            GatewayApiError::RouteError(_) => StatusCode::INTERNAL_SERVER_ERROR,
            GatewayApiError::RoutedExecutorError(_) => StatusCode::INTERNAL_SERVER_ERROR,
            GatewayApiError::TokenUsageLimit => StatusCode::BAD_REQUEST,
        }
    }
}