2021-06-19 19:39:41 +00:00
|
|
|
use actix_web::{http::StatusCode, HttpResponse, ResponseError};
|
2021-09-14 01:22:42 +00:00
|
|
|
use tracing_error::SpanTrace;
|
|
|
|
|
|
|
|
pub(crate) struct Error {
|
|
|
|
context: SpanTrace,
|
|
|
|
kind: UploadError,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::fmt::Debug for Error {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
2021-10-28 04:06:03 +00:00
|
|
|
writeln!(f, "{}", self.kind)
|
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 {
|
2021-10-28 04:06:03 +00:00
|
|
|
writeln!(f, "{}", self.kind)?;
|
2022-03-27 01:45:12 +00:00
|
|
|
writeln!(f)?;
|
|
|
|
let mut count = 0;
|
|
|
|
let mut source = std::error::Error::source(self);
|
|
|
|
if source.is_some() {
|
|
|
|
writeln!(f, "Chain:")?;
|
|
|
|
}
|
|
|
|
while let Some(err) = source {
|
|
|
|
write!(f, "{}. ", count)?;
|
|
|
|
writeln!(f, "{}", err)?;
|
|
|
|
|
|
|
|
count += 1;
|
|
|
|
source = std::error::Error::source(err);
|
|
|
|
}
|
|
|
|
|
2021-09-14 01:22:42 +00:00
|
|
|
std::fmt::Display::fmt(&self.context, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::error::Error for Error {
|
|
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
|
|
|
self.kind.source()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> From<T> for Error
|
|
|
|
where
|
|
|
|
UploadError: From<T>,
|
|
|
|
{
|
|
|
|
fn from(error: T) -> Self {
|
|
|
|
Error {
|
|
|
|
kind: UploadError::from(error),
|
|
|
|
context: SpanTrace::capture(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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")]
|
2022-03-27 01:45:12 +00:00
|
|
|
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")]
|
2021-10-28 04:06:03 +00:00
|
|
|
ObjectStore(#[from] crate::store::object_store::ObjectError),
|
|
|
|
|
2021-10-21 02:36:18 +00:00
|
|
|
#[error("Provided process path is invalid")]
|
|
|
|
ParsePath,
|
|
|
|
|
2021-09-04 21:01:48 +00:00
|
|
|
#[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
|
|
|
|
2020-06-07 15:59:58 +00:00
|
|
|
#[error("Unsupported image format")]
|
|
|
|
UnsupportedFormat,
|
|
|
|
|
2021-09-14 01:22:42 +00:00
|
|
|
#[error("Invalid media dimensions")]
|
|
|
|
Dimensions,
|
|
|
|
|
2020-06-07 15:59:58 +00:00
|
|
|
#[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),
|
2020-06-07 15:59:58 +00:00
|
|
|
|
|
|
|
#[error("Unable to send request, {0}")]
|
|
|
|
SendRequest(String),
|
2020-06-07 17:51:45 +00:00
|
|
|
|
|
|
|
#[error("No filename provided in request")]
|
|
|
|
MissingFilename,
|
2020-06-09 23:39:49 +00:00
|
|
|
|
|
|
|
#[error("Error converting Path to String")]
|
|
|
|
Path,
|
2020-06-11 00:26:54 +00:00
|
|
|
|
|
|
|
#[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")]
|
2020-12-10 05:05:04 +00:00
|
|
|
Json(#[from] serde_json::Error),
|
2021-01-14 13:52:11 +00:00
|
|
|
|
|
|
|
#[error("Range header not satisfiable")]
|
|
|
|
Range,
|
2021-08-28 22:15:14 +00:00
|
|
|
|
2022-03-26 21:49:23 +00:00
|
|
|
#[error("Hit limit")]
|
2021-10-20 23:58:32 +00:00
|
|
|
Limit(#[from] super::LimitError),
|
2020-06-07 15:59:58 +00:00
|
|
|
}
|
|
|
|
|
2021-03-10 02:51:03 +00:00
|
|
|
impl From<awc::error::SendRequestError> for UploadError {
|
|
|
|
fn from(e: awc::error::SendRequestError) -> Self {
|
2020-06-07 15:59:58 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-04 21:01:48 +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 {
|
2021-09-14 01:22:42 +00:00
|
|
|
match self.kind {
|
|
|
|
UploadError::DuplicateAlias
|
2021-10-20 23:58:32 +00:00
|
|
|
| UploadError::Limit(_)
|
2020-06-11 00:26:54 +00:00
|
|
|
| UploadError::NoFiles
|
2022-03-01 17:23:15 +00:00
|
|
|
| UploadError::Upload(_) => StatusCode::BAD_REQUEST,
|
2020-06-07 17:51:45 +00:00
|
|
|
UploadError::MissingAlias | UploadError::MissingFilename => StatusCode::NOT_FOUND,
|
2020-06-07 00:29:15 +00:00
|
|
|
UploadError::InvalidToken => StatusCode::FORBIDDEN,
|
2021-01-14 13:52:11 +00:00
|
|
|
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 {
|
|
|
|
HttpResponse::build(self.status_code())
|
2021-04-17 19:59:42 +00:00
|
|
|
.content_type("application/json")
|
|
|
|
.body(
|
2021-09-14 01:22:42 +00:00
|
|
|
serde_json::to_string(&serde_json::json!({ "msg": self.kind.to_string() }))
|
|
|
|
.unwrap_or_else(|_| r#"{"msg":"Request failed"}"#.to_string()),
|
2021-04-17 19:59:42 +00:00
|
|
|
)
|
2020-06-06 21:41:17 +00:00
|
|
|
}
|
|
|
|
}
|