use axum::Json;
use axum::body::Body;
use axum::http;
use axum::response::IntoResponse;
use axum::response::Response;
use hyper::StatusCode;
use serde::Deserialize;
use serde::Serialize;
use serde_json::json;
use thiserror::Error;
use tonic::Status;
#[derive(Error, Debug)]
pub enum DemoError {}
#[derive(Error, Debug)]
pub enum ProxyError {
#[error("Invalid configuration: {0}")]
InvalidConfiguration(String),
#[error("Network error: {0}")]
NetworkError(#[from] reqwest::Error),
#[error("Hyper error: {0}")]
HyperError(#[from] hyper::Error),
#[error("Axum error: {0}")]
AxumError(#[from] axum::http::Error),
#[error("HttpHeaderNameError error: {0}")]
HttpHeaderNameError(#[from] http::header::InvalidHeaderName),
#[error("HttpHeaderValueError error: {0}")]
HttpHeaderValueError(#[from] http::header::InvalidHeaderValue),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("gRPC error: {0}")]
GrpcError(#[from] tonic::Status),
#[error("aborting processing now")]
GrpcAbort(Response<Vec<u8>>),
#[error("RPC call error to '{0}' during '{1}': {2}")]
RpcCallError(String, String, Status),
#[error("RPC connection error to '{0}': {1}")]
RpcConnectionError(String, String),
#[error("Invalid request: {0}")]
InvalidRequest(String),
#[error("Other error: {0}")]
Other(String),
#[error("Internal error: {0}")]
Internal(String),
#[error("rust tls error: {0}")]
TlsError(#[from] tokio_rustls::rustls::Error),
}
impl IntoResponse for ProxyError {
fn into_response(self) -> Response<Body> {
let (status, error_message) = match self {
ProxyError::InvalidConfiguration(msg) => (
StatusCode::BAD_REQUEST,
json!({ "error": format!("Invalid Configuration: {}", msg) }),
),
ProxyError::NetworkError(err) => (
StatusCode::BAD_GATEWAY,
json!({ "error": format!("Network Error: {}", err) }),
),
ProxyError::HyperError(err) => (
StatusCode::BAD_GATEWAY,
json!({ "error": format!("Hyper Error: {}", err) }),
),
ProxyError::IoError(err) => (
StatusCode::INTERNAL_SERVER_ERROR,
json!({ "error": format!("IO Error: {}", err) }),
),
ProxyError::GrpcError(err) => (
StatusCode::BAD_GATEWAY,
json!({ "error": format!("gRPC Error: {}", err) }),
),
ProxyError::RpcCallError(plugin, method, msg) => (
StatusCode::BAD_REQUEST,
json!({
"error": format!("RPC Call Error in plugin '{}', method '{}': {}", plugin, method, msg)
}),
),
ProxyError::RpcConnectionError(plugin, msg) => (
StatusCode::BAD_GATEWAY,
json!({
"error": format!("RPC Connection Error to plugin '{}': {}", plugin, msg)
}),
),
ProxyError::InvalidRequest(msg) => (
StatusCode::BAD_REQUEST,
json!({ "error": format!("Invalid Request: {}", msg) }),
),
ProxyError::Other(msg) => (
StatusCode::INTERNAL_SERVER_ERROR,
json!({ "error": format!("Other Error: {}", msg) }),
),
ProxyError::Internal(msg) => (
StatusCode::INTERNAL_SERVER_ERROR,
json!({ "error": format!("Internal Server Error: {}", msg) }),
),
ProxyError::HttpHeaderNameError(invalid_header_name) => (
StatusCode::INTERNAL_SERVER_ERROR,
json!({ "error": format!("Invalid HTTP header name: {}", invalid_header_name) }),
),
ProxyError::HttpHeaderValueError(invalid_header_value) => (
StatusCode::INTERNAL_SERVER_ERROR,
json!({ "error": format!("Invalid HTTP header value: {}", invalid_header_value) }),
),
ProxyError::AxumError(..) => (
StatusCode::INTERNAL_SERVER_ERROR,
json!({ "error": format!("Invalid Axum body value") }),
),
ProxyError::GrpcAbort(..) => todo!(),
ProxyError::TlsError(error) => (
StatusCode::INTERNAL_SERVER_ERROR,
json!({ "error": format!("Tls error: {}", error) }),
),
};
(status, Json(error_message)).into_response()
}
}
#[cfg(feature = "scenario")]
#[derive(Clone, Error, Debug, Serialize, Deserialize)]
pub enum ScenarioError {
#[error("IO error: {0}")]
IoError(String),
#[error("Report error: {0}")]
ReportError(String),
#[error("Failed to read file {0}: {1}")]
ReadError(String, String),
#[error("Failed to parse YAML in file {0}: {1}")]
ParseError(String, String),
#[error("WalkDir error: {0}")]
WalkDirError(String),
#[error("Invalid HTTP method header: {0}")]
HTTPMethodError(String),
#[error("HTTP error: {0}")]
HTTPError(String),
#[error("Missing OpenAPI version")]
MissingOpenAPIVersion(),
#[error("Unsupported OpenAPI version: {0}")]
UnsupportedOpenAPIVersion(String),
#[error("Failed to parse OpenAPI: {0}")]
OpenAPIParsingError(String),
#[error("Expected a directory to store multiple scenarios")]
ExpectedDirectoryError(),
}
#[derive(Error, Debug)]
pub enum SchedulingError {
#[error(
"Fraction-based time spec ('{0}') used but no --duration provided.\nHint: Please specify a duration (e.g., --duration=10s) when using fraction-based time specs."
)]
MissingDuration(String),
#[error(
"Unknown key ('{0}') used in schedule.\nHint: Only `start` and `duration` are allowed."
)]
UnknownKey(String),
#[error("Time spec ('{0}') could not be parsed.")]
FailedParsing(String),
#[error("Invalid time fraction ('{0}') in time spec.")]
InvalidFraction(String),
}
#[derive(Error, Debug)]
pub enum SuggestionError {
#[error("Invalid diff hunk: {0}")]
InvalidHunk(String),
#[error("Failed to retrieve: {0}")]
Retrieval(String),
}
#[derive(Error, Debug)]
pub enum APIServiceError {}