#[cfg(feature = "nothuman")] use actix_web::HttpResponse; use actix_web::ResponseError; use derive_more::From; use std::fmt::{self, Display}; pub type Result = std::result::Result; #[derive(From, Debug)] pub enum Error { Reqwest(reqwest::Error), #[cfg(feature = "nothuman")] NotHuman { target: String }, } impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self) } } impl ResponseError for Error { fn status_code(&self) -> reqwest::StatusCode { use reqwest::StatusCode; use Error::*; match self { // Theoretically could be 503 Service Unavailable in case remote is actually down, // but will also throw for network errors, so a generic 500 Internal Server Error is more appropriate. Reqwest(error) => error.status().unwrap_or(StatusCode::INTERNAL_SERVER_ERROR), // 403 Forbidden #[cfg(feature = "nothuman")] NotHuman { .. } => StatusCode::FORBIDDEN, } } #[cfg(feature = "nothuman")] fn error_response(&self) -> HttpResponse { HttpResponse::build(self.status_code()).body(match self { Self::NotHuman { target } => format!( "It looks like you're accessing the Tatoeba API proxy from a script!\n\ Tatoeba CORS restrictions do not apply outside of browsers, so please access the API directly:\n\ {target}\n\ If you feel this is mistake, please open an issue:\n\ https://codeberg.org/ElnuDev/tatoeba-api-rs"), _ => self.to_string(), }) } }