use ave_bridge::BridgeError;
use ave_bridge::Error as CoreError;
use axum::{
Json,
http::StatusCode,
response::{IntoResponse, Response},
};
use serde::Serialize;
#[derive(Serialize)]
struct ErrorBody {
error: String,
#[serde(skip_serializing_if = "Option::is_none")]
trackers: Option<Vec<String>>,
}
pub struct HttpError(BridgeError);
impl From<BridgeError> for HttpError {
fn from(err: BridgeError) -> Self {
Self(err)
}
}
impl IntoResponse for HttpError {
fn into_response(self) -> Response {
let status = status_for_bridge_error(&self.0);
let body = match &self.0 {
BridgeError::Core(CoreError::GovernanceHasTrackers {
trackers,
..
}) => ErrorBody {
error: self.0.to_string(),
trackers: Some(trackers.clone()),
},
_ => ErrorBody {
error: self.0.to_string(),
trackers: None,
},
};
(status, Json(body)).into_response()
}
}
const fn status_for_bridge_error(err: &BridgeError) -> StatusCode {
match err {
BridgeError::InvalidSubjectId(_)
| BridgeError::InvalidRequestId(_)
| BridgeError::InvalidPublicKey(_)
| BridgeError::InvalidSignature(_)
| BridgeError::InvalidEventRequest(_) => StatusCode::BAD_REQUEST,
BridgeError::KeyDecrypt(_) => StatusCode::UNAUTHORIZED,
BridgeError::KeyDirectoryCreation(_)
| BridgeError::KeyRead(_)
| BridgeError::KeyRestore(_)
| BridgeError::KeyGeneration(_)
| BridgeError::KeyEncrypt(_)
| BridgeError::KeyWrite(_) => StatusCode::INTERNAL_SERVER_ERROR,
BridgeError::ConfigBuild(_) | BridgeError::ConfigDeserialize(_) => {
StatusCode::INTERNAL_SERVER_ERROR
}
BridgeError::SinkAuth(_) => StatusCode::INTERNAL_SERVER_ERROR,
BridgeError::Core(core) => status_for_core_error(core),
}
}
const fn status_for_core_error(err: &CoreError) -> StatusCode {
match err {
CoreError::InvalidSignature(_)
| CoreError::InvalidSubjectId(_)
| CoreError::InvalidQueryParams(_)
| CoreError::InvalidEventRequest(_) => StatusCode::BAD_REQUEST,
CoreError::Unauthorized(_) => StatusCode::UNAUTHORIZED,
CoreError::Forbidden(_) => StatusCode::FORBIDDEN,
CoreError::SafeMode(_) => StatusCode::SERVICE_UNAVAILABLE,
CoreError::RequestNotFound(_)
| CoreError::ApprovalNotFound(_)
| CoreError::SubjectNotFound(_)
| CoreError::GovernanceNotFound(_)
| CoreError::WitnessesNotFound(_)
| CoreError::NoEventsFound(_)
| CoreError::EventNotFound { .. }
| CoreError::NoPendingTransfers => StatusCode::NOT_FOUND,
CoreError::InvalidRequestState(_)
| CoreError::InvalidApprovalState(_)
| CoreError::SubjectNotActive(_)
| CoreError::GovernanceHasTrackers { .. } => StatusCode::CONFLICT,
CoreError::RequestProcessing(_)
| CoreError::ValidationFailed(_)
| CoreError::SchemaValidation(_) => StatusCode::UNPROCESSABLE_ENTITY,
CoreError::NotImplemented(_) => StatusCode::NOT_IMPLEMENTED,
CoreError::Network(_) | CoreError::NetworkState(_) => {
StatusCode::BAD_GATEWAY
}
CoreError::Timeout(_) => StatusCode::GATEWAY_TIMEOUT,
CoreError::SystemInit(_)
| CoreError::ActorCreation { .. }
| CoreError::MissingResource { .. }
| CoreError::SigningFailed(_)
| CoreError::ApprovalUpdateFailed(_)
| CoreError::AuthOperation(_)
| CoreError::QueryFailed(_)
| CoreError::DatabaseError(_)
| CoreError::ActorCommunication { .. }
| CoreError::UnexpectedResponse { .. }
| CoreError::ActorError(_)
| CoreError::TransferFailed(_)
| CoreError::DistributionFailed(_)
| CoreError::UpdateFailed(_, _)
| CoreError::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
}
}