use eth2::types::ErrorMessage; use std::convert::Infallible; use warp::{http::StatusCode, reject::Reject}; #[derive(Debug)] pub struct BeaconChainError(pub beacon_chain::BeaconChainError); impl Reject for BeaconChainError {} pub fn beacon_chain_error(e: beacon_chain::BeaconChainError) -> warp::reject::Rejection { warp::reject::custom(BeaconChainError(e)) } #[derive(Debug)] pub struct BeaconStateError(pub types::BeaconStateError); impl Reject for BeaconStateError {} pub fn beacon_state_error(e: types::BeaconStateError) -> warp::reject::Rejection { warp::reject::custom(BeaconStateError(e)) } #[derive(Debug)] pub struct ArithError(pub safe_arith::ArithError); impl Reject for ArithError {} pub fn arith_error(e: safe_arith::ArithError) -> warp::reject::Rejection { warp::reject::custom(ArithError(e)) } #[derive(Debug)] pub struct SlotProcessingError(pub state_processing::SlotProcessingError); impl Reject for SlotProcessingError {} pub fn slot_processing_error(e: state_processing::SlotProcessingError) -> warp::reject::Rejection { warp::reject::custom(SlotProcessingError(e)) } #[derive(Debug)] pub struct BlockProductionError(pub beacon_chain::BlockProductionError); impl Reject for BlockProductionError {} pub fn block_production_error(e: beacon_chain::BlockProductionError) -> warp::reject::Rejection { warp::reject::custom(BlockProductionError(e)) } #[derive(Debug)] pub struct CustomNotFound(pub String); impl Reject for CustomNotFound {} pub fn custom_not_found(msg: String) -> warp::reject::Rejection { warp::reject::custom(CustomNotFound(msg)) } #[derive(Debug)] pub struct CustomBadRequest(pub String); impl Reject for CustomBadRequest {} pub fn custom_bad_request(msg: String) -> warp::reject::Rejection { warp::reject::custom(CustomBadRequest(msg)) } #[derive(Debug)] pub struct CustomServerError(pub String); impl Reject for CustomServerError {} pub fn custom_server_error(msg: String) -> warp::reject::Rejection { warp::reject::custom(CustomServerError(msg)) } #[derive(Debug)] pub struct BroadcastWithoutImport(pub String); impl Reject for BroadcastWithoutImport {} pub fn broadcast_without_import(msg: String) -> warp::reject::Rejection { warp::reject::custom(BroadcastWithoutImport(msg)) } #[derive(Debug)] pub struct ObjectInvalid(pub String); impl Reject for ObjectInvalid {} pub fn object_invalid(msg: String) -> warp::reject::Rejection { warp::reject::custom(ObjectInvalid(msg)) } #[derive(Debug)] pub struct NotSynced(pub String); impl Reject for NotSynced {} pub fn not_synced(msg: String) -> warp::reject::Rejection { warp::reject::custom(NotSynced(msg)) } #[derive(Debug)] pub struct InvalidAuthorization(pub String); impl Reject for InvalidAuthorization {} pub fn invalid_auth(msg: String) -> warp::reject::Rejection { warp::reject::custom(InvalidAuthorization(msg)) } /// This function receives a `Rejection` and tries to return a custom /// value, otherwise simply passes the rejection along. pub async fn handle_rejection(err: warp::Rejection) -> Result { let code; let message; if err.is_not_found() { code = StatusCode::NOT_FOUND; message = "NOT_FOUND".to_string(); } else if let Some(e) = err.find::() { message = format!("BAD_REQUEST: body deserialize error: {}", e); code = StatusCode::BAD_REQUEST; } else if let Some(e) = err.find::() { code = StatusCode::BAD_REQUEST; message = format!("BAD_REQUEST: invalid query: {}", e); } else if let Some(e) = err.find::() { code = StatusCode::INTERNAL_SERVER_ERROR; message = format!("UNHANDLED_ERROR: {:?}", e.0); } else if let Some(e) = err.find::() { code = StatusCode::INTERNAL_SERVER_ERROR; message = format!("UNHANDLED_ERROR: {:?}", e.0); } else if let Some(e) = err.find::() { code = StatusCode::INTERNAL_SERVER_ERROR; message = format!("UNHANDLED_ERROR: {:?}", e.0); } else if let Some(e) = err.find::() { code = StatusCode::INTERNAL_SERVER_ERROR; message = format!("UNHANDLED_ERROR: {:?}", e.0); } else if let Some(e) = err.find::() { code = StatusCode::NOT_FOUND; message = format!("NOT_FOUND: {}", e.0); } else if let Some(e) = err.find::() { code = StatusCode::BAD_REQUEST; message = format!("BAD_REQUEST: {}", e.0); } else if let Some(e) = err.find::() { code = StatusCode::INTERNAL_SERVER_ERROR; message = format!("INTERNAL_SERVER_ERROR: {}", e.0); } else if let Some(e) = err.find::() { code = StatusCode::ACCEPTED; message = format!( "ACCEPTED: the object was broadcast to the network without being \ fully imported to the local database: {}", e.0 ); } else if let Some(e) = err.find::() { code = StatusCode::BAD_REQUEST; message = format!("BAD_REQUEST: Invalid object: {}", e.0); } else if let Some(e) = err.find::() { code = StatusCode::SERVICE_UNAVAILABLE; message = format!("SERVICE_UNAVAILABLE: beacon node is syncing: {}", e.0); } else if let Some(e) = err.find::() { code = StatusCode::FORBIDDEN; message = format!("FORBIDDEN: Invalid auth token: {}", e.0); } else if let Some(e) = err.find::() { code = StatusCode::BAD_REQUEST; message = format!("BAD_REQUEST: missing {} header", e.name()); } else if let Some(e) = err.find::() { code = StatusCode::BAD_REQUEST; message = format!("BAD_REQUEST: invalid {} header", e.name()); } else if err.find::().is_some() { code = StatusCode::METHOD_NOT_ALLOWED; message = "METHOD_NOT_ALLOWED".to_string(); } else { code = StatusCode::INTERNAL_SERVER_ERROR; message = "UNHANDLED_REJECTION".to_string(); } let json = warp::reply::json(&ErrorMessage { code: code.as_u16(), message, stacktraces: vec![], }); Ok(warp::reply::with_status(json, code)) }