refactor: make the serverside error handling more robust

This commit is contained in:
Matouš Volf
2024-08-18 19:09:40 +02:00
parent a78f6bac94
commit 38be8af169
12 changed files with 301 additions and 43 deletions

29
src/errors/error.rs Normal file
View File

@ -0,0 +1,29 @@
use serde::{Deserialize, Serialize};
use std::fmt::Display;
use std::str::FromStr;
#[derive(Serialize, Deserialize, Debug)]
pub enum Error {
ServerInternal,
}
// has to be implemented for Dioxus server functions
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::ServerInternal => write!(f, "internal server error"),
}
}
}
// has to be implemented for Dioxus server functions
impl FromStr for Error {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"internal server error" => Error::ServerInternal,
_ => return Err(()),
})
}
}

43
src/errors/error_vec.rs Normal file
View File

@ -0,0 +1,43 @@
use std::fmt::Display;
use std::str::FromStr;
#[derive(Debug)]
pub struct ErrorVec<T> {
errors: Vec<T>,
}
impl<T> From<ErrorVec<T>> for Vec<T> {
fn from(e: ErrorVec<T>) -> Self {
e.errors
}
}
impl<T> From<Vec<T>> for ErrorVec<T> {
fn from(e: Vec<T>) -> Self {
ErrorVec { errors: e }
}
}
// has to be implemented for Dioxus server functions
impl<T: Display> Display for ErrorVec<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
self.errors
.iter()
.map(|e| e.to_string())
.collect::<Vec<String>>()
.join("\n")
)
}
}
// has to be implemented for Dioxus server functions
impl<T> FromStr for ErrorVec<T> {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(ErrorVec { errors: Vec::new() })
}
}

3
src/errors/mod.rs Normal file
View File

@ -0,0 +1,3 @@
pub(crate) mod error;
pub(crate) mod error_vec;
pub(crate) mod project_create_error;

View File

@ -0,0 +1,50 @@
use crate::errors::error::Error;
use crate::errors::error_vec::ErrorVec;
use serde::{Deserialize, Serialize};
use std::fmt::Display;
use std::str::FromStr;
use validator::{ValidationErrors, ValidationErrorsKind};
#[derive(Serialize, Deserialize, Debug)]
pub enum ProjectCreateError {
TitleTooShort,
Error(Error),
}
impl From<ValidationErrors> for ErrorVec<ProjectCreateError> {
fn from(e: ValidationErrors) -> Self {
e.errors()
.iter()
.flat_map(|(&field, error_kind)| match field {
"title_length" => match error_kind {
ValidationErrorsKind::Field(validation_errors) => validation_errors
.iter()
.map(|validation_error| match validation_error.code.as_ref() {
"length" => ProjectCreateError::TitleTooShort,
_ => ProjectCreateError::Error(Error::ServerInternal),
})
.collect::<Vec<ProjectCreateError>>(),
_ => panic!("unexpected error kind"),
},
_ => panic!("unexpected field name"),
})
.collect::<Vec<ProjectCreateError>>()
.into()
}
}
// has to be implemented for Dioxus server functions
impl Display for ProjectCreateError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", dbg!(self))
}
}
// has to be implemented for Dioxus server functions
impl FromStr for ProjectCreateError {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(ProjectCreateError::Error(Error::ServerInternal))
}
}