feat(server): start proper error handling

main
Jef Roosens 2023-07-14 13:46:53 +02:00
parent 2a6bd46661
commit 5a5ab7ad52
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
3 changed files with 56 additions and 18 deletions

View File

@ -0,0 +1,45 @@
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use std::error::Error;
use std::fmt;
use std::io;
pub type Result<T> = std::result::Result<T, ServerError>;
#[derive(Debug)]
pub enum ServerError {
IO(io::Error),
Axum(axum::Error),
}
impl fmt::Display for ServerError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ServerError::IO(err) => write!(fmt, "{}", err),
ServerError::Axum(err) => write!(fmt, "{}", err),
}
}
}
impl Error for ServerError {}
impl IntoResponse for ServerError {
fn into_response(self) -> Response {
match self {
ServerError::IO(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
ServerError::Axum(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
}
}
}
impl From<io::Error> for ServerError {
fn from(err: io::Error) -> Self {
ServerError::IO(err)
}
}
impl From<axum::Error> for ServerError {
fn from(err: axum::Error) -> Self {
ServerError::Axum(err)
}
}

View File

@ -1,5 +1,8 @@
mod error;
mod repo; mod repo;
pub use error::{Result, ServerError};
use axum::extract::FromRef; use axum::extract::FromRef;
use axum::Router; use axum::Router;
use repo::RepoGroupManager; use repo::RepoGroupManager;

View File

@ -34,35 +34,25 @@ pub fn router(global: &crate::Global) -> Router<crate::Global> {
async fn post_package_archive( async fn post_package_archive(
State(global): State<crate::Global>, State(global): State<crate::Global>,
Path(repo): Path<String>, Path(repo): Path<String>,
body: BodyStream, mut body: BodyStream,
) -> Result<(), StatusCode> { ) -> crate::Result<()> {
// let mut body_reader = tokio_util::io::StreamReader::new( // let mut body_reader = tokio_util::io::StreamReader::new(
// body.map_err(|err| io::Error::new(io::ErrorKind::Other, err)), // body.map_err(|err| io::Error::new(io::ErrorKind::Other, err)),
// ); // );
let mut body = body.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR);
// We first stream the uploaded file to disk // We first stream the uploaded file to disk
let uuid: uuid::fmt::Simple = Uuid::new_v4().into(); let uuid: uuid::fmt::Simple = Uuid::new_v4().into();
let path = global.config.pkg_dir.join(uuid.to_string()); let path = global.config.pkg_dir.join(uuid.to_string());
let mut f = fs::File::create(&path) let mut f = fs::File::create(&path).await?;
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)
.await?;
while let Some(chunk) = body.next().await { while let Some(chunk) = body.next().await {
f.write_all(&chunk?) f.write_all(&chunk?).await?;
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)
.await?;
} }
let clone = Arc::clone(&global.repo_manager); let clone = Arc::clone(&global.repo_manager);
tokio::task::spawn_blocking(move || clone.write().unwrap().add_pkg_from_path(&repo, &path)) tokio::task::spawn_blocking(move || clone.write().unwrap().add_pkg_from_path(&repo, &path))
.map_err(|err| { .await
println!("{}", err); .map_err(io::Error::from)??;
StatusCode::INTERNAL_SERVER_ERROR
}) Ok(())
.await?
.map_err(|err| {
println!("{}", err);
StatusCode::INTERNAL_SERVER_ERROR
})
} }