mirror of
https://github.com/MedzikUser/HomeDisk.git
synced 2024-08-14 21:46:53 +00:00
chore: update errors types
This commit is contained in:
parent
dcaee9d641
commit
c745b9db96
10 changed files with 58 additions and 99 deletions
|
@ -13,7 +13,5 @@ pub fn init() {
|
||||||
better_panic::install();
|
better_panic::install();
|
||||||
|
|
||||||
// initialize tracing
|
// initialize tracing
|
||||||
tracing_subscriber::fmt()
|
tracing_subscriber::fmt().with_max_level(MAX_LEVEL).init();
|
||||||
.with_max_level(MAX_LEVEL)
|
|
||||||
.init();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,7 @@
|
||||||
|
|
||||||
mod sqlite;
|
mod sqlite;
|
||||||
|
|
||||||
/// Imported from [homedisk_types::database::User].
|
|
||||||
pub use homedisk_types::database::User;
|
pub use homedisk_types::database::User;
|
||||||
/// Imported from [homedisk_types::errors::DatabaseError].
|
|
||||||
pub use homedisk_types::errors::DatabaseError as Error;
|
pub use homedisk_types::errors::DatabaseError as Error;
|
||||||
/// Imported from [homedisk_types::errors::DatabaseResult].
|
|
||||||
pub use homedisk_types::errors::DatabaseResult as Result;
|
pub use homedisk_types::errors::DatabaseResult as Result;
|
||||||
pub use sqlite::*;
|
pub use sqlite::*;
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use futures_util::TryStreamExt;
|
use futures_util::TryStreamExt;
|
||||||
use sqlx::{sqlite::{SqliteQueryResult, SqliteConnectOptions}, Executor, Row, SqlitePool, ConnectOptions};
|
use sqlx::{
|
||||||
use tracing::{log::LevelFilter, debug};
|
sqlite::{SqliteConnectOptions, SqliteQueryResult},
|
||||||
|
ConnectOptions, Executor, Row, SqlitePool,
|
||||||
|
};
|
||||||
|
use tracing::{debug, log::LevelFilter};
|
||||||
|
|
||||||
use super::{Error, Result, User};
|
use super::{Error, Result, User};
|
||||||
|
|
||||||
|
@ -31,13 +34,15 @@ impl Database {
|
||||||
debug!("Opening SQLite database");
|
debug!("Opening SQLite database");
|
||||||
|
|
||||||
// sqlite connection options
|
// sqlite connection options
|
||||||
let mut options = SqliteConnectOptions::from_str(path)?;
|
let mut options = SqliteConnectOptions::from_str(path).map_err(Error::OpenDatabase)?;
|
||||||
|
|
||||||
// set log level to Debug
|
// set log level to Debug
|
||||||
options.log_statements(LevelFilter::Debug);
|
options.log_statements(LevelFilter::Debug);
|
||||||
|
|
||||||
// create a database pool
|
// create a database pool
|
||||||
let conn = SqlitePool::connect_with(options.clone()).await?;
|
let conn = SqlitePool::connect_with(options.clone())
|
||||||
|
.await
|
||||||
|
.map_err(Error::ConnectDatabase)?;
|
||||||
|
|
||||||
// return `Database`
|
// return `Database`
|
||||||
Ok(Self { conn })
|
Ok(Self { conn })
|
||||||
|
@ -54,7 +59,7 @@ impl Database {
|
||||||
pub async fn create_tables(&self) -> Result<SqliteQueryResult> {
|
pub async fn create_tables(&self) -> Result<SqliteQueryResult> {
|
||||||
let query = sqlx::query(include_str!("../../tables.sql"));
|
let query = sqlx::query(include_str!("../../tables.sql"));
|
||||||
|
|
||||||
Ok(self.conn.execute(query).await?)
|
self.conn.execute(query).await.map_err(Error::Execute)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new User
|
/// Create a new User
|
||||||
|
@ -82,7 +87,7 @@ impl Database {
|
||||||
.bind(&user.password);
|
.bind(&user.password);
|
||||||
|
|
||||||
// execute query and return output
|
// execute query and return output
|
||||||
Ok(self.conn.execute(query).await?)
|
self.conn.execute(query).await.map_err(Error::Execute)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Search for a user
|
/// Search for a user
|
||||||
|
@ -113,14 +118,18 @@ impl Database {
|
||||||
let mut stream = self.conn.fetch(query);
|
let mut stream = self.conn.fetch(query);
|
||||||
|
|
||||||
// get rows from query
|
// get rows from query
|
||||||
let row = stream.try_next().await?.ok_or(Error::UserNotFound)?;
|
let row = stream
|
||||||
|
.try_next()
|
||||||
|
.await
|
||||||
|
.map_err(Error::Execute)?
|
||||||
|
.ok_or(Error::UserNotFound)?;
|
||||||
|
|
||||||
// get `id` row
|
// get `id` row
|
||||||
let id = row.try_get("id")?;
|
let id = row.try_get("id").map_err(Error::GetRow)?;
|
||||||
// get `username` row
|
// get `username` row
|
||||||
let username = row.try_get("username")?;
|
let username = row.try_get("username").map_err(Error::GetRow)?;
|
||||||
// get `password` row
|
// get `password` row
|
||||||
let password = row.try_get("password")?;
|
let password = row.try_get("password").map_err(Error::GetRow)?;
|
||||||
|
|
||||||
// return `User`
|
// return `User`
|
||||||
Ok(User {
|
Ok(User {
|
||||||
|
@ -155,14 +164,18 @@ impl Database {
|
||||||
let mut stream = self.conn.fetch(query);
|
let mut stream = self.conn.fetch(query);
|
||||||
|
|
||||||
// get rows from query
|
// get rows from query
|
||||||
let row = stream.try_next().await?.ok_or(Error::UserNotFound)?;
|
let row = stream
|
||||||
|
.try_next()
|
||||||
|
.await
|
||||||
|
.map_err(Error::Execute)?
|
||||||
|
.ok_or(Error::UserNotFound)?;
|
||||||
|
|
||||||
// get `id` row
|
// get `id` row
|
||||||
let id = row.try_get("id")?;
|
let id = row.try_get("id").map_err(Error::GetRow)?;
|
||||||
// get `username` row
|
// get `username` row
|
||||||
let username = row.try_get("username")?;
|
let username = row.try_get("username").map_err(Error::GetRow)?;
|
||||||
// get `password` row
|
// get `password` row
|
||||||
let password = row.try_get("password")?;
|
let password = row.try_get("password").map_err(Error::GetRow)?;
|
||||||
|
|
||||||
// return `User`
|
// return `User`
|
||||||
Ok(User {
|
Ok(User {
|
||||||
|
@ -243,7 +256,7 @@ mod tests {
|
||||||
assert_eq!(err.to_string(), "user not found")
|
assert_eq!(err.to_string(), "user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test a search for a user who does not exist
|
/// Test a search for a user who doesn't exist
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn find_user_wrong_username() {
|
async fn find_user_wrong_username() {
|
||||||
let db = open_db().await;
|
let db = open_db().await;
|
||||||
|
@ -257,7 +270,7 @@ mod tests {
|
||||||
assert_eq!(err.to_string(), "user not found")
|
assert_eq!(err.to_string(), "user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test a search for a user by UUID who does not exist
|
/// Test a search for a user by UUID who doesn't exist
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn find_user_wrong_id() {
|
async fn find_user_wrong_id() {
|
||||||
let db = open_db().await;
|
let db = open_db().await;
|
||||||
|
|
|
@ -29,7 +29,7 @@ pub async fn handle(
|
||||||
Response::LoggedIn {
|
Response::LoggedIn {
|
||||||
access_token: token,
|
access_token: token,
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
// error while searching for a user
|
// error while searching for a user
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -39,7 +39,7 @@ pub async fn handle(
|
||||||
// other error
|
// other error
|
||||||
_ => Err(ServerError::AuthError(AuthError::Other(err.to_string()))),
|
_ => Err(ServerError::AuthError(AuthError::Other(err.to_string()))),
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Json(response))
|
Ok(Json(response))
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub async fn handle(
|
||||||
Response::LoggedIn {
|
Response::LoggedIn {
|
||||||
access_token: token,
|
access_token: token,
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
// error while searching for a user
|
// error while searching for a user
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -53,7 +53,7 @@ pub async fn handle(
|
||||||
|
|
||||||
// other error
|
// other error
|
||||||
return Err(ServerError::AuthError(AuthError::Other(err.to_string())));
|
return Err(ServerError::AuthError(AuthError::Other(err.to_string())));
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// create directory for user files
|
// create directory for user files
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub async fn find_user(db: &Database, user_id: &str) -> Result<User, ServerError
|
||||||
// user not found
|
// user not found
|
||||||
homedisk_database::Error::UserNotFound => {
|
homedisk_database::Error::UserNotFound => {
|
||||||
Err(ServerError::AuthError(AuthError::UserNotFound))
|
Err(ServerError::AuthError(AuthError::UserNotFound))
|
||||||
}
|
},
|
||||||
// other error
|
// other error
|
||||||
_ => Err(ServerError::AuthError(AuthError::Other(err.to_string()))),
|
_ => Err(ServerError::AuthError(AuthError::Other(err.to_string()))),
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,28 +3,20 @@ use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Error)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Username or Password incorrect.
|
|
||||||
#[error("user not found")]
|
#[error("user not found")]
|
||||||
UserNotFound,
|
UserNotFound,
|
||||||
/// Cannot create a user because username already exists.
|
|
||||||
#[error("user already exists")]
|
#[error("user already exists")]
|
||||||
UserAlreadyExists,
|
UserAlreadyExists,
|
||||||
/// Username is too short.
|
|
||||||
#[error("username is too short")]
|
#[error("username is too short")]
|
||||||
UsernameTooShort,
|
UsernameTooShort,
|
||||||
/// Username is too long.
|
|
||||||
#[error("username is too long")]
|
#[error("username is too long")]
|
||||||
UsernameTooLong,
|
UsernameTooLong,
|
||||||
/// Password is too short.
|
|
||||||
#[error("password is too short")]
|
#[error("password is too short")]
|
||||||
PasswordTooShort,
|
PasswordTooShort,
|
||||||
/// Failed to generate user token.
|
#[error("failed to generate jwt token")]
|
||||||
#[error("generate jwt token")]
|
|
||||||
TokenGenerate,
|
TokenGenerate,
|
||||||
/// Incorrect user token.
|
|
||||||
#[error("invalid jwt token")]
|
#[error("invalid jwt token")]
|
||||||
InvalidToken,
|
InvalidToken,
|
||||||
/// Other error.
|
|
||||||
#[error("other error - {0}")]
|
#[error("other error - {0}")]
|
||||||
Other(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,27 +3,16 @@ use thiserror::Error;
|
||||||
/// Database Error
|
/// Database Error
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Username or Password incorrect.
|
|
||||||
#[error("user not found")]
|
#[error("user not found")]
|
||||||
UserNotFound,
|
UserNotFound,
|
||||||
/// [sqlx::Error](https://docs.rs/sqlx/latest/sqlx/enum.Error.html)
|
#[error("failed to open database: {0}")]
|
||||||
#[error("sqlx error - {0}")]
|
OpenDatabase(sqlx::Error),
|
||||||
SQLx(sqlx::Error),
|
#[error("failed to connect to the database: {0}")]
|
||||||
/// [std::io::Error]
|
ConnectDatabase(sqlx::Error),
|
||||||
#[error("std::io error - {0}")]
|
#[error("failed to get row: {0}")]
|
||||||
StdIo(std::io::Error),
|
GetRow(sqlx::Error),
|
||||||
}
|
#[error("failed to execute the query: {0}")]
|
||||||
|
Execute(sqlx::Error),
|
||||||
impl From<sqlx::Error> for Error {
|
|
||||||
fn from(err: sqlx::Error) -> Self {
|
|
||||||
Error::SQLx(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<std::io::Error> for Error {
|
|
||||||
fn from(err: std::io::Error) -> Self {
|
|
||||||
Error::StdIo(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Custom Result alias for a [enum@Error].
|
/// Custom Result alias for a [enum@Error].
|
||||||
|
|
|
@ -3,37 +3,26 @@ use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Error)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// File doesn't exists.
|
|
||||||
#[error("file doesn't exists")]
|
#[error("file doesn't exists")]
|
||||||
FileDoesNotExist,
|
FileDoesNotExist,
|
||||||
/// File already exists.
|
|
||||||
#[error("file already exists")]
|
#[error("file already exists")]
|
||||||
FileAlreadyExists,
|
FileAlreadyExists,
|
||||||
/// Error when parsing multipart.
|
|
||||||
#[error("unexpected multipart error")]
|
#[error("unexpected multipart error")]
|
||||||
MultipartError,
|
MultipartError,
|
||||||
/// Failed to create a file.
|
#[error("failed to create create a file - {0}")]
|
||||||
#[error("create file - {0}")]
|
|
||||||
CreateFile(String),
|
CreateFile(String),
|
||||||
/// Failed to create a directory.
|
#[error("failed to create a directory - {0}")]
|
||||||
#[error("create dir - {0}")]
|
|
||||||
CreateDirectory(String),
|
CreateDirectory(String),
|
||||||
/// Failed to delete file.
|
#[error("failed to delete file: {0}")]
|
||||||
#[error("delete file - {0}")]
|
|
||||||
DeleteFile(String),
|
DeleteFile(String),
|
||||||
/// Failed to delete directory.
|
#[error("failed to delete directory: {0}")]
|
||||||
#[error("delete dir - {0}")]
|
|
||||||
DeleteDirectory(String),
|
DeleteDirectory(String),
|
||||||
/// Failed to write content to file.
|
#[error("failed to write content to file: {0}")]
|
||||||
#[error("write file - {0}")]
|
|
||||||
WriteFile(String),
|
WriteFile(String),
|
||||||
/// Failed decoding base64.
|
#[error("failed to decode base64: {0}")]
|
||||||
#[error("base64 - {0}")]
|
|
||||||
Base64(String),
|
Base64(String),
|
||||||
/// Error when paths in directory.
|
#[error("failed to read directory: {0}")]
|
||||||
#[error("read dir - {0}")]
|
|
||||||
ReadDirectory(String),
|
ReadDirectory(String),
|
||||||
/// Other error.
|
|
||||||
#[error("other error - {0}")]
|
#[error("other error - {0}")]
|
||||||
Other(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,29 +7,21 @@ use super::{AuthError, FsError};
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Error)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Error)]
|
||||||
#[serde(tag = "error", content = "error_message", rename_all = "kebab-case")]
|
#[serde(tag = "error", content = "error_message", rename_all = "kebab-case")]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Auth error.
|
|
||||||
#[error("auth error - {0}")]
|
#[error("auth error - {0}")]
|
||||||
AuthError(#[from] AuthError),
|
AuthError(#[from] AuthError),
|
||||||
/// File System Error.
|
|
||||||
#[error("fs error - {0}")]
|
#[error("fs error - {0}")]
|
||||||
FsError(#[from] FsError),
|
FsError(#[from] FsError),
|
||||||
/// User sends too many requests.
|
|
||||||
#[error("too may requests, please slow down")]
|
#[error("too may requests, please slow down")]
|
||||||
TooManyRequests,
|
TooManyRequests,
|
||||||
/// Missing Json in Content-Type Header.
|
#[error("missing json in Content-Type header")]
|
||||||
#[error("missing json content type")]
|
|
||||||
MissingJsonContentType,
|
MissingJsonContentType,
|
||||||
/// Failed to deserialize JSON.
|
#[error("failed to deserialize json")]
|
||||||
#[error("error deserialize json")]
|
|
||||||
JsonDataError,
|
JsonDataError,
|
||||||
/// Syntax error in JSON.
|
#[error("syntax error in json")]
|
||||||
#[error("json syntax error")]
|
|
||||||
JsonSyntaxError,
|
JsonSyntaxError,
|
||||||
/// Failed to extract the Request body.
|
|
||||||
#[error("failed to extract the request body")]
|
#[error("failed to extract the request body")]
|
||||||
BytesRejection,
|
BytesRejection,
|
||||||
/// Other error.
|
#[error("other error - {0}")]
|
||||||
#[error("unknown error - {0}")]
|
|
||||||
Other(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,34 +32,23 @@ impl axum::response::IntoResponse for Error {
|
||||||
|
|
||||||
let status = match self {
|
let status = match self {
|
||||||
Self::AuthError(ref err) => match err {
|
Self::AuthError(ref err) => match err {
|
||||||
AuthError::UserNotFound => StatusCode::BAD_REQUEST,
|
|
||||||
AuthError::UserAlreadyExists => StatusCode::BAD_REQUEST,
|
|
||||||
AuthError::UsernameTooShort => StatusCode::BAD_REQUEST,
|
|
||||||
AuthError::UsernameTooLong => StatusCode::BAD_REQUEST,
|
|
||||||
AuthError::PasswordTooShort => StatusCode::BAD_REQUEST,
|
|
||||||
AuthError::TokenGenerate => StatusCode::INTERNAL_SERVER_ERROR,
|
AuthError::TokenGenerate => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
AuthError::InvalidToken => StatusCode::BAD_REQUEST,
|
|
||||||
AuthError::Other(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
AuthError::Other(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
_ => StatusCode::BAD_REQUEST,
|
||||||
},
|
},
|
||||||
Self::FsError(ref err) => match err {
|
Self::FsError(ref err) => match err {
|
||||||
FsError::FileAlreadyExists => StatusCode::BAD_REQUEST,
|
|
||||||
FsError::FileDoesNotExist => StatusCode::BAD_REQUEST,
|
|
||||||
FsError::MultipartError => StatusCode::BAD_REQUEST,
|
|
||||||
FsError::CreateFile(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
FsError::CreateFile(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
FsError::CreateDirectory(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
FsError::CreateDirectory(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
FsError::DeleteFile(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
FsError::DeleteFile(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
FsError::DeleteDirectory(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
FsError::DeleteDirectory(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
FsError::WriteFile(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
FsError::WriteFile(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
FsError::Base64(_) => StatusCode::BAD_REQUEST,
|
|
||||||
FsError::ReadDirectory(_) => StatusCode::BAD_REQUEST,
|
|
||||||
FsError::Other(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
FsError::Other(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
_ => StatusCode::BAD_REQUEST,
|
||||||
},
|
},
|
||||||
Self::TooManyRequests => StatusCode::TOO_MANY_REQUESTS,
|
Self::TooManyRequests => StatusCode::TOO_MANY_REQUESTS,
|
||||||
Self::MissingJsonContentType => StatusCode::BAD_REQUEST,
|
|
||||||
Self::JsonDataError => StatusCode::BAD_REQUEST,
|
|
||||||
Self::JsonSyntaxError => StatusCode::BAD_REQUEST,
|
|
||||||
Self::BytesRejection => StatusCode::INTERNAL_SERVER_ERROR,
|
Self::BytesRejection => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
Self::Other(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
Self::Other(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
_ => StatusCode::BAD_REQUEST,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut response = axum::Json(self).into_response();
|
let mut response = axum::Json(self).into_response();
|
||||||
|
|
Loading…
Reference in a new issue