|
|
|
#[cfg(feature = "nothuman")]
|
|
|
|
use actix_web::HttpResponse;
|
|
|
|
|
|
|
|
use actix_web::ResponseError;
|
|
|
|
use derive_more::From;
|
|
|
|
use std::fmt::{self, Display};
|
|
|
|
|
|
|
|
pub type Result<T> = std::result::Result<T, Error>;
|
|
|
|
|
|
|
|
#[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<actix_web::body::BoxBody> {
|
|
|
|
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(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|