2021-12-29 18:33:31 +01:00
|
|
|
use std::convert::Infallible;
|
|
|
|
|
|
|
|
use axum::{
|
|
|
|
body::{Bytes, Full},
|
2022-01-11 19:42:15 +01:00
|
|
|
extract::{multipart::MultipartError, rejection::QueryRejection},
|
2021-12-29 18:33:31 +01:00
|
|
|
response::IntoResponse,
|
|
|
|
Json,
|
|
|
|
};
|
|
|
|
use reqwest::StatusCode;
|
2022-01-02 17:25:23 +01:00
|
|
|
use thiserror::Error;
|
2021-12-29 18:33:31 +01:00
|
|
|
|
|
|
|
use super::models::ErrorResponse;
|
2022-01-05 23:46:19 +01:00
|
|
|
use crate::ipfs::error::IPFSError;
|
2021-12-29 18:33:31 +01:00
|
|
|
|
2022-01-02 17:25:23 +01:00
|
|
|
#[derive(Error, Debug)]
|
|
|
|
pub enum APIError {
|
|
|
|
#[error("SQL error: {0}")]
|
|
|
|
Sql(#[from] sqlx::Error),
|
|
|
|
#[error("Multipart form error: {0}")]
|
|
|
|
Multipart(#[from] MultipartError),
|
2022-01-08 20:57:53 +01:00
|
|
|
#[error("{0}")]
|
2022-01-02 17:25:23 +01:00
|
|
|
BadRequest(String),
|
2022-01-08 20:57:53 +01:00
|
|
|
#[error("{0}")]
|
|
|
|
Unauthorized(String),
|
|
|
|
#[error("{0}")]
|
|
|
|
Forbidden(String),
|
2022-01-08 23:52:15 +01:00
|
|
|
#[error("{0}")]
|
|
|
|
Internal(String),
|
2022-01-05 23:46:19 +01:00
|
|
|
#[error("IPFS error: {0}")]
|
2022-01-10 14:37:27 +01:00
|
|
|
Ipfs(#[from] IPFSError),
|
2022-01-11 19:42:15 +01:00
|
|
|
#[error("Query rejection: {0}")]
|
|
|
|
Query(#[from] QueryRejection),
|
2022-01-02 17:25:23 +01:00
|
|
|
}
|
|
|
|
|
2021-12-29 18:33:31 +01:00
|
|
|
impl ErrorResponse {
|
|
|
|
fn new(status: StatusCode, message: Option<String>) -> Self {
|
2022-01-02 17:25:23 +01:00
|
|
|
let reason = status.canonical_reason().unwrap_or_default();
|
|
|
|
Self {
|
2021-12-29 18:33:31 +01:00
|
|
|
status,
|
2022-01-10 14:37:27 +01:00
|
|
|
error: message.unwrap_or_else(|| reason.to_string()),
|
2021-12-29 18:33:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-02 17:25:23 +01:00
|
|
|
impl IntoResponse for APIError {
|
2021-12-29 18:33:31 +01:00
|
|
|
type Body = Full<Bytes>;
|
|
|
|
|
|
|
|
type BodyError = Infallible;
|
|
|
|
|
|
|
|
fn into_response(self) -> axum::http::Response<Self::Body> {
|
2022-01-02 17:25:23 +01:00
|
|
|
let res = match self {
|
|
|
|
APIError::Sql(err) => match err {
|
|
|
|
sqlx::Error::RowNotFound => ErrorResponse::new(StatusCode::NOT_FOUND, None),
|
|
|
|
_ => ErrorResponse::new(StatusCode::INTERNAL_SERVER_ERROR, None),
|
|
|
|
},
|
|
|
|
APIError::Multipart(_) => ErrorResponse::new(StatusCode::INTERNAL_SERVER_ERROR, None),
|
|
|
|
APIError::BadRequest(err) => ErrorResponse::new(StatusCode::BAD_REQUEST, Some(err)),
|
2022-01-08 20:57:53 +01:00
|
|
|
APIError::Unauthorized(err) => ErrorResponse::new(StatusCode::UNAUTHORIZED, Some(err)),
|
|
|
|
APIError::Forbidden(err) => ErrorResponse::new(StatusCode::FORBIDDEN, Some(err)),
|
2022-01-08 23:52:15 +01:00
|
|
|
APIError::Internal(err) => {
|
|
|
|
ErrorResponse::new(StatusCode::INTERNAL_SERVER_ERROR, Some(err))
|
|
|
|
}
|
2022-01-10 14:37:27 +01:00
|
|
|
APIError::Ipfs(_) => ErrorResponse::new(StatusCode::INTERNAL_SERVER_ERROR, None),
|
2022-01-11 19:42:15 +01:00
|
|
|
APIError::Query(_) => ErrorResponse::new(StatusCode::BAD_REQUEST, None),
|
2022-01-02 17:25:23 +01:00
|
|
|
};
|
2022-01-10 14:37:27 +01:00
|
|
|
let status = res.status;
|
2022-01-02 17:25:23 +01:00
|
|
|
(status, Json(res)).into_response()
|
2021-12-29 18:33:31 +01:00
|
|
|
}
|
|
|
|
}
|