pict-rs/src/error.rs

181 lines
4.9 KiB
Rust
Raw Normal View History

2021-06-19 19:39:41 +00:00
use actix_web::{http::StatusCode, HttpResponse, ResponseError};
2022-03-29 01:47:46 +00:00
use color_eyre::Report;
2021-09-14 01:22:42 +00:00
pub(crate) struct Error {
2022-03-29 01:47:46 +00:00
inner: color_eyre::Report,
}
impl Error {
fn kind(&self) -> Option<&UploadError> {
self.inner.downcast_ref()
}
2021-09-14 01:22:42 +00:00
}
impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2022-03-29 01:47:46 +00:00
std::fmt::Debug::fmt(&self.inner, f)
2021-09-14 01:22:42 +00:00
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2022-03-29 01:47:46 +00:00
std::fmt::Display::fmt(&self.inner, f)
2021-09-14 01:22:42 +00:00
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
2022-03-29 01:47:46 +00:00
self.inner.source()
2021-09-14 01:22:42 +00:00
}
}
impl<T> From<T> for Error
where
UploadError: From<T>,
{
fn from(error: T) -> Self {
Error {
2022-03-29 01:47:46 +00:00
inner: Report::from(UploadError::from(error)),
2021-09-14 01:22:42 +00:00
}
}
}
2020-06-06 21:41:17 +00:00
#[derive(Debug, thiserror::Error)]
2020-06-11 16:46:00 +00:00
pub(crate) enum UploadError {
2022-03-26 21:49:23 +00:00
#[error("Couln't upload file")]
2021-09-14 01:50:51 +00:00
Upload(#[from] actix_form_data::Error),
2020-06-06 21:41:17 +00:00
2022-03-26 21:49:23 +00:00
#[error("Error in DB")]
Sled(#[from] crate::repo::sled::SledError),
2022-03-26 21:49:23 +00:00
#[error("Error in old sled DB")]
OldSled(#[from] ::sled::Error),
2020-06-06 21:41:17 +00:00
2022-03-26 21:49:23 +00:00
#[error("Error parsing string")]
2020-06-06 21:41:17 +00:00
ParseString(#[from] std::string::FromUtf8Error),
2022-03-26 21:49:23 +00:00
#[error("Error interacting with filesystem")]
2020-06-07 00:29:15 +00:00
Io(#[from] std::io::Error),
2022-03-26 21:49:23 +00:00
#[error("Error generating path")]
2021-10-19 01:29:06 +00:00
PathGenerator(#[from] storage_path_generator::PathError),
2022-03-26 21:49:23 +00:00
#[error("Error stripping prefix")]
2021-10-19 01:29:06 +00:00
StripPrefix(#[from] std::path::StripPrefixError),
2022-03-26 21:49:23 +00:00
#[error("Error storing file")]
2021-10-23 04:48:56 +00:00
FileStore(#[from] crate::store::file_store::FileError),
2022-03-26 21:49:23 +00:00
#[error("Error storing object")]
ObjectStore(#[from] crate::store::object_store::ObjectError),
2021-10-21 02:36:18 +00:00
#[error("Provided process path is invalid")]
ParsePath,
#[error("Failed to acquire the semaphore")]
Semaphore,
2020-06-06 21:41:17 +00:00
#[error("Panic in blocking operation")]
Canceled,
#[error("No files present in upload")]
NoFiles,
2020-06-06 22:43:33 +00:00
#[error("Requested a file that doesn't exist")]
MissingAlias,
2020-06-07 00:29:15 +00:00
#[error("Provided token did not match expected token")]
InvalidToken,
2020-06-07 01:44:26 +00:00
#[error("Unsupported image format")]
UnsupportedFormat,
2022-03-29 16:04:56 +00:00
#[error("Gif uploads are not enabled")]
SilentVideoDisabled,
2021-09-14 01:22:42 +00:00
#[error("Invalid media dimensions")]
Dimensions,
#[error("Unable to download image, bad response {0}")]
Download(actix_web::http::StatusCode),
2022-03-26 21:49:23 +00:00
#[error("Unable to download image")]
2021-03-10 02:51:03 +00:00
Payload(#[from] awc::error::PayloadError),
#[error("Unable to send request, {0}")]
SendRequest(String),
#[error("Error converting Path to String")]
Path,
#[error("Tried to save an image with an already-taken name")]
DuplicateAlias,
2020-06-11 16:46:00 +00:00
2022-03-26 21:49:23 +00:00
#[error("Error in json")]
Json(#[from] serde_json::Error),
#[error("Range header not satisfiable")]
Range,
2022-03-26 21:49:23 +00:00
#[error("Hit limit")]
2021-10-20 23:58:32 +00:00
Limit(#[from] super::LimitError),
}
2021-03-10 02:51:03 +00:00
impl From<awc::error::SendRequestError> for UploadError {
fn from(e: awc::error::SendRequestError) -> Self {
UploadError::SendRequest(e.to_string())
}
2020-06-07 00:29:15 +00:00
}
2021-02-10 22:57:42 +00:00
impl From<actix_web::error::BlockingError> for UploadError {
fn from(_: actix_web::error::BlockingError) -> Self {
UploadError::Canceled
2020-06-06 21:41:17 +00:00
}
}
impl From<tokio::sync::AcquireError> for UploadError {
fn from(_: tokio::sync::AcquireError) -> Self {
UploadError::Semaphore
}
}
2021-09-14 01:22:42 +00:00
impl ResponseError for Error {
2020-06-06 21:41:17 +00:00
fn status_code(&self) -> StatusCode {
2022-03-29 01:47:46 +00:00
match self.kind() {
Some(
UploadError::DuplicateAlias
| UploadError::Limit(_)
| UploadError::NoFiles
2022-03-29 16:04:56 +00:00
| UploadError::Upload(_)
| UploadError::UnsupportedFormat
| UploadError::SilentVideoDisabled,
2022-03-29 01:47:46 +00:00
) => StatusCode::BAD_REQUEST,
Some(
UploadError::Sled(crate::repo::sled::SledError::Missing)
| UploadError::MissingAlias,
) => StatusCode::NOT_FOUND,
Some(UploadError::InvalidToken) => StatusCode::FORBIDDEN,
Some(UploadError::Range) => StatusCode::RANGE_NOT_SATISFIABLE,
2020-06-06 21:41:17 +00:00
_ => StatusCode::INTERNAL_SERVER_ERROR,
}
}
2021-06-19 19:39:41 +00:00
fn error_response(&self) -> HttpResponse {
2022-03-29 01:47:46 +00:00
if let Some(kind) = self.kind() {
HttpResponse::build(self.status_code())
.content_type("application/json")
.body(
serde_json::to_string(&serde_json::json!({ "msg": kind.to_string() }))
.unwrap_or_else(|_| r#"{"msg":"Request failed"}"#.to_string()),
)
} else {
HttpResponse::build(self.status_code())
.content_type("application/json")
.body(
serde_json::to_string(&serde_json::json!({ "msg": "Unknown error" }))
.unwrap_or_else(|_| r#"{"msg":"Request failed"}"#.to_string()),
)
}
2020-06-06 21:41:17 +00:00
}
}