#[cfg(any(feature = "openai", feature = "anthropic", feature = "google"))]
use std::fmt;
#[cfg(any(feature = "openai", feature = "anthropic", feature = "google"))]
use bitrouter_core::errors::BitrouterError;
#[cfg(any(feature = "openai", feature = "anthropic", feature = "google"))]
use warp::reject::Reject;
#[derive(Debug)]
#[cfg(any(feature = "openai", feature = "anthropic", feature = "google"))]
pub(crate) struct BitrouterRejection(pub BitrouterError);
#[cfg(any(feature = "openai", feature = "anthropic", feature = "google"))]
impl fmt::Display for BitrouterRejection {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[cfg(any(feature = "openai", feature = "anthropic", feature = "google"))]
impl Reject for BitrouterRejection {}
#[derive(Debug)]
#[cfg(feature = "openai")]
pub(crate) struct BadRequest(pub String);
#[cfg(feature = "openai")]
impl fmt::Display for BadRequest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[cfg(feature = "openai")]
impl Reject for BadRequest {}
#[cfg(any(feature = "openai", feature = "anthropic", feature = "google"))]
pub fn handle_bitrouter_rejection(err: &warp::Rejection) -> Option<warp::http::Response<String>> {
use warp::http::StatusCode;
if let Some(e) = err.find::<BitrouterRejection>() {
let (status, error_type) = match &e.0 {
BitrouterError::InvalidRequest { .. } | BitrouterError::UnsupportedFeature { .. } => {
(StatusCode::BAD_REQUEST, "invalid_request_error")
}
BitrouterError::AccessDenied { .. } => (StatusCode::FORBIDDEN, "access_denied"),
BitrouterError::Cancelled { .. } => (StatusCode::BAD_REQUEST, "cancelled"),
BitrouterError::Provider { context, .. } => {
let status = context
.status_code
.and_then(|code| StatusCode::from_u16(code).ok())
.unwrap_or(StatusCode::BAD_GATEWAY);
(status, "provider_error")
}
BitrouterError::Transport { .. }
| BitrouterError::ResponseDecode { .. }
| BitrouterError::InvalidResponse { .. }
| BitrouterError::StreamProtocol { .. } => (StatusCode::BAD_GATEWAY, "upstream_error"),
};
let body = serde_json::json!({
"error": {
"message": e.0.to_string(),
"type": error_type,
}
})
.to_string();
let response = warp::http::Response::builder()
.status(status)
.header("content-type", "application/json")
.body(body)
.ok()?;
return Some(response);
}
#[cfg(feature = "openai")]
if let Some(e) = err.find::<BadRequest>() {
let body = serde_json::json!({
"error": {
"message": e.to_string(),
"type": "invalid_request_error",
}
})
.to_string();
let response = warp::http::Response::builder()
.status(StatusCode::BAD_REQUEST)
.header("content-type", "application/json")
.body(body)
.ok()?;
return Some(response);
}
None
}