Files
Genarrative/server-rs/crates/platform-hyper3d/src/error.rs
2026-05-26 13:18:13 +08:00

181 lines
4.8 KiB
Rust

use std::{error::Error, fmt};
use crate::HYPER3D_PROVIDER;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Hyper3dStatusHint {
BadRequest,
ServiceUnavailable,
BadGateway,
GatewayTimeout,
}
#[derive(Clone, Debug)]
pub enum Hyper3dError {
InvalidConfig {
provider: &'static str,
reason: Option<&'static str>,
message: String,
},
InvalidRequest {
provider: &'static str,
field: Option<&'static str>,
message: String,
allowed: Option<Vec<String>>,
},
Request {
provider: &'static str,
message: String,
endpoint: Option<String>,
timeout: bool,
connect: bool,
request: bool,
body: bool,
status_code: Option<u16>,
source: Option<String>,
},
Upstream {
provider: &'static str,
message: String,
upstream_status: u16,
raw_excerpt: String,
},
ResponseParse {
provider: &'static str,
message: String,
raw_excerpt: String,
},
MissingField {
provider: &'static str,
message: String,
},
}
impl Hyper3dError {
pub fn provider(&self) -> &'static str {
match self {
Self::InvalidConfig { provider, .. }
| Self::InvalidRequest { provider, .. }
| Self::Request { provider, .. }
| Self::Upstream { provider, .. }
| Self::ResponseParse { provider, .. }
| Self::MissingField { provider, .. } => provider,
}
}
pub fn message(&self) -> &str {
match self {
Self::InvalidConfig { message, .. }
| Self::InvalidRequest { message, .. }
| Self::Request { message, .. }
| Self::Upstream { message, .. }
| Self::ResponseParse { message, .. }
| Self::MissingField { message, .. } => message,
}
}
pub fn status_hint(&self) -> Hyper3dStatusHint {
match self {
Self::InvalidConfig { .. } => Hyper3dStatusHint::ServiceUnavailable,
Self::InvalidRequest { .. } => Hyper3dStatusHint::BadRequest,
Self::Request { timeout, .. } if *timeout => Hyper3dStatusHint::GatewayTimeout,
Self::Request { .. }
| Self::Upstream { .. }
| Self::ResponseParse { .. }
| Self::MissingField { .. } => Hyper3dStatusHint::BadGateway,
}
}
pub fn invalid_config(reason: &'static str, message: impl Into<String>) -> Self {
Self::InvalidConfig {
provider: HYPER3D_PROVIDER,
reason: Some(reason),
message: message.into(),
}
}
pub(crate) fn invalid_request(field: Option<&'static str>, message: impl Into<String>) -> Self {
Self::InvalidRequest {
provider: HYPER3D_PROVIDER,
field,
message: message.into(),
allowed: None,
}
}
pub(crate) fn invalid_request_allowed(
field: &'static str,
message: impl Into<String>,
allowed: &[&str],
) -> Self {
Self::InvalidRequest {
provider: HYPER3D_PROVIDER,
field: Some(field),
message: message.into(),
allowed: Some(allowed.iter().map(|value| value.to_string()).collect()),
}
}
pub(crate) fn request(
message: impl Into<String>,
endpoint: Option<String>,
timeout: bool,
connect: bool,
request: bool,
body: bool,
status_code: Option<u16>,
source: Option<String>,
) -> Self {
Self::Request {
provider: HYPER3D_PROVIDER,
message: message.into(),
endpoint,
timeout,
connect,
request,
body,
status_code,
source,
}
}
pub(crate) fn upstream(
message: impl Into<String>,
upstream_status: u16,
raw_excerpt: impl Into<String>,
) -> Self {
Self::Upstream {
provider: HYPER3D_PROVIDER,
message: message.into(),
upstream_status,
raw_excerpt: raw_excerpt.into(),
}
}
pub(crate) fn response_parse(
message: impl Into<String>,
raw_excerpt: impl Into<String>,
) -> Self {
Self::ResponseParse {
provider: HYPER3D_PROVIDER,
message: message.into(),
raw_excerpt: raw_excerpt.into(),
}
}
pub(crate) fn missing_field(message: impl Into<String>) -> Self {
Self::MissingField {
provider: HYPER3D_PROVIDER,
message: message.into(),
}
}
}
impl fmt::Display for Hyper3dError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(self.message())
}
}
impl Error for Hyper3dError {}