From 9e6e7733a3856df034765f69f65a5a75fe49996e Mon Sep 17 00:00:00 2001 From: naskya <m@naskya.net> Date: Tue, 11 Jun 2024 19:49:44 +0900 Subject: [PATCH] chore (backend-rs): improve error messages refs: https://rust-lang.github.io/api-guidelines/interoperability.html https://github.com/rust-lang/project-error-handling/issues/27 --- packages/backend-rs/src/database/cache.rs | 6 ++-- packages/backend-rs/src/database/redis.rs | 4 +-- packages/backend-rs/src/federation/acct.rs | 1 + .../src/federation/nodeinfo/fetch.rs | 13 +++++---- .../src/federation/nodeinfo/generate.rs | 5 ++-- packages/backend-rs/src/misc/convert_host.rs | 7 +++-- .../backend-rs/src/misc/get_image_size.rs | 29 ++++++++++++------- .../backend-rs/src/misc/latest_version.rs | 19 ++++++------ packages/backend-rs/src/misc/password.rs | 8 ++--- packages/backend-rs/src/misc/reaction.rs | 5 ++-- .../src/service/antenna/check_hit.rs | 5 ++-- .../src/service/antenna/process_new_note.rs | 16 +++++----- .../src/service/push_notification.rs | 12 ++++---- packages/backend-rs/src/service/stream.rs | 12 ++++---- packages/backend-rs/src/util/http_client.rs | 4 +-- packages/backend-rs/src/util/id.rs | 3 +- 16 files changed, 83 insertions(+), 66 deletions(-) diff --git a/packages/backend-rs/src/database/cache.rs b/packages/backend-rs/src/database/cache.rs index c49806afdf..1dcd81d9ec 100644 --- a/packages/backend-rs/src/database/cache.rs +++ b/packages/backend-rs/src/database/cache.rs @@ -15,11 +15,11 @@ pub enum Category { #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("Redis error: {0}")] + #[error("failed to execute Redis command")] Redis(#[from] RedisError), - #[error("Redis connection error: {0}")] + #[error("bad Redis connection")] RedisConn(#[from] RedisConnError), - #[error("Failed to encode the data: {0}")] + #[error("failed to encode data for Redis")] Encode(#[from] rmp_serde::encode::Error), } diff --git a/packages/backend-rs/src/database/redis.rs b/packages/backend-rs/src/database/redis.rs index f40cd011c2..3207e5cbbd 100644 --- a/packages/backend-rs/src/database/redis.rs +++ b/packages/backend-rs/src/database/redis.rs @@ -81,9 +81,9 @@ async fn init_conn_pool() -> Result<(), RedisError> { #[derive(thiserror::Error, Debug)] pub enum RedisConnError { - #[error("Failed to initialize Redis connection pool: {0}")] + #[error("failed to initialize Redis connection pool")] Redis(RedisError), - #[error("Redis connection pool error: {0}")] + #[error("bad Redis connection pool")] Bb8Pool(RunError<RedisError>), } diff --git a/packages/backend-rs/src/federation/acct.rs b/packages/backend-rs/src/federation/acct.rs index ffc972ba84..b07cb71448 100644 --- a/packages/backend-rs/src/federation/acct.rs +++ b/packages/backend-rs/src/federation/acct.rs @@ -8,6 +8,7 @@ pub struct Acct { } #[derive(thiserror::Error, Debug)] +#[doc = "Error type to indicate a string-to-[`Acct`] conversion failure"] #[error("failed to convert string '{0}' into acct")] pub struct InvalidAcctString(String); diff --git a/packages/backend-rs/src/federation/nodeinfo/fetch.rs b/packages/backend-rs/src/federation/nodeinfo/fetch.rs index 1b963e086c..89a325e597 100644 --- a/packages/backend-rs/src/federation/nodeinfo/fetch.rs +++ b/packages/backend-rs/src/federation/nodeinfo/fetch.rs @@ -9,17 +9,18 @@ use serde::Deserialize; /// Errors that can occur while fetching NodeInfo from a remote server #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("HTTP client aquisition error: {0}")] + #[error("failed to acquire an HTTP client")] HttpClient(#[from] http_client::Error), - #[error("HTTP error: {0}")] + #[error("HTTP request failed")] Http(#[from] isahc::Error), - #[error("Bad status: {0}")] + #[doc = "bad HTTP status"] + #[error("bad HTTP status ({0})")] BadStatus(String), - #[error("Failed to parse response body as text: {0}")] + #[error("failed to parse HTTP response body as text")] Response(#[from] std::io::Error), - #[error("Failed to parse response body as json: {0}")] + #[error("failed to parse HTTP response body as json")] Json(#[from] serde_json::Error), - #[error("No nodeinfo provided")] + #[error("nodeinfo is missing")] MissingNodeinfo, } diff --git a/packages/backend-rs/src/federation/nodeinfo/generate.rs b/packages/backend-rs/src/federation/nodeinfo/generate.rs index e83fb059b1..b37652637c 100644 --- a/packages/backend-rs/src/federation/nodeinfo/generate.rs +++ b/packages/backend-rs/src/federation/nodeinfo/generate.rs @@ -154,9 +154,10 @@ pub async fn nodeinfo_2_0() -> Result<Nodeinfo20, DbErr> { #[cfg(feature = "napi")] #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("Database error: {0}")] + #[doc = "database error"] + #[error(transparent)] Db(#[from] DbErr), - #[error("Failed to serialize nodeinfo into JSON: {0}")] + #[error("failed to serialize nodeinfo into JSON")] Json(#[from] serde_json::Error), } diff --git a/packages/backend-rs/src/misc/convert_host.rs b/packages/backend-rs/src/misc/convert_host.rs index c086285af1..2850d4cb29 100644 --- a/packages/backend-rs/src/misc/convert_host.rs +++ b/packages/backend-rs/src/misc/convert_host.rs @@ -4,11 +4,12 @@ #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("Idna error: {0}")] + #[doc = "UTS #46 process has failed"] + #[error(transparent)] Idna(#[from] idna::Errors), - #[error("Url parse error: {0}")] + #[error("failed to parse a URL")] UrlParse(#[from] url::ParseError), - #[error("Hostname is missing")] + #[error("hostname is missing")] NoHostname, } diff --git a/packages/backend-rs/src/misc/get_image_size.rs b/packages/backend-rs/src/misc/get_image_size.rs index 78c40cf5a1..31d5bb398f 100644 --- a/packages/backend-rs/src/misc/get_image_size.rs +++ b/packages/backend-rs/src/misc/get_image_size.rs @@ -7,23 +7,26 @@ use tokio::sync::Mutex; #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("Redis cache error: {0}")] + #[error("Redis cache operation has failed")] Cache(#[from] cache::Error), - #[error("HTTP client aquisition error: {0}")] + #[error("failed to acquire an HTTP client")] HttpClient(#[from] http_client::Error), - #[error("Isahc error: {0}")] + #[error("HTTP request failed")] Isahc(#[from] isahc::Error), - #[error("HTTP error: {0}")] - Http(String), - #[error("Image decoding error: {0}")] + #[doc = "bad HTTP status"] + #[error("bad HTTP status ({0})")] + BadStatus(String), + #[error("failed to decode an image")] Image(#[from] ImageError), - #[error("Image decoding error: {0}")] + #[error("failed to decode an image")] Io(#[from] std::io::Error), - #[error("Exif extraction error: {0}")] + #[error("failed to extract the exif data")] Exif(#[from] nom_exif::Error), - #[error("Emoji meta attempt limit exceeded: {0}")] + #[doc = "too many fetch attempts"] + #[error("too many fetch attempts for {0}")] TooManyAttempts(String), - #[error("Unsupported image type: {0}")] + #[doc = "unsupported image type"] + #[error("unsupported image type ({0})")] UnsupportedImage(String), } @@ -75,7 +78,11 @@ pub async fn get_image_size_from_url(url: &str) -> Result<ImageSize, Error> { if !response.status().is_success() { tracing::info!("status: {}", response.status()); tracing::debug!("response body: {:#?}", response.body()); - return Err(Error::Http(format!("Failed to get image from {}", url))); + return Err(Error::BadStatus(format!( + "{} returned {}", + url, + response.status() + ))); } let image_bytes = response.bytes().await?; diff --git a/packages/backend-rs/src/misc/latest_version.rs b/packages/backend-rs/src/misc/latest_version.rs index f6453249b8..ad1d6b2fc7 100644 --- a/packages/backend-rs/src/misc/latest_version.rs +++ b/packages/backend-rs/src/misc/latest_version.rs @@ -6,17 +6,18 @@ use serde::Deserialize; #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("Cache error: {0}")] + #[error("Redis cache operation has failed")] Cache(#[from] cache::Error), - #[error("Isahc error: {0}")] + #[error("HTTP request failed")] Isahc(#[from] isahc::Error), - #[error("HTTP client aquisition error: {0}")] + #[error("failed to acquire an HTTP client")] HttpClient(#[from] http_client::Error), - #[error("HTTP error: {0}")] - Http(String), - #[error("Response parsing error: {0}")] + #[doc = "firefish.dev returned bad HTTP status"] + #[error("firefish.dev returned bad HTTP status ({0})")] + BadStatus(String), + #[error("failed to parse the HTTP response")] Io(#[from] std::io::Error), - #[error("Failed to deserialize JSON: {0}")] + #[error("failed to parse the HTTP response as JSON")] Json(#[from] serde_json::Error), } @@ -36,9 +37,7 @@ async fn get_latest_version() -> Result<String, Error> { if !response.status().is_success() { tracing::info!("status: {}", response.status()); tracing::debug!("response body: {:#?}", response.body()); - return Err(Error::Http( - "Failed to fetch version from Firefish GitLab".to_string(), - )); + return Err(Error::BadStatus(response.status().to_string())); } let res_parsed: Response = serde_json::from_str(&response.text().await?)?; diff --git a/packages/backend-rs/src/misc/password.rs b/packages/backend-rs/src/misc/password.rs index df18efd5a3..b23b305e32 100644 --- a/packages/backend-rs/src/misc/password.rs +++ b/packages/backend-rs/src/misc/password.rs @@ -17,12 +17,12 @@ pub fn hash_password(password: &str) -> Result<String, password_hash::errors::Er #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("An error occured while bcrypt verification: {0}")] + #[error("failed to verify password against bcrypt hash")] Bcrypt(#[from] bcrypt::BcryptError), - #[error("Invalid argon2 password hash: {0}")] - InvalidArgon2Hash(#[from] password_hash::Error), - #[error("An error occured while argon2 verification: {0}")] + #[error("failed to verify password against argon2 hash")] Argon2(#[from] argon2::Error), + #[error("invalid argon2 password hash")] + InvalidArgon2Hash(#[from] password_hash::Error), } /// Checks whether the given password and hash match. diff --git a/packages/backend-rs/src/misc/reaction.rs b/packages/backend-rs/src/misc/reaction.rs index 5ea8385a00..662e6ac766 100644 --- a/packages/backend-rs/src/misc/reaction.rs +++ b/packages/backend-rs/src/misc/reaction.rs @@ -55,9 +55,10 @@ pub fn count_reactions(reactions: &HashMap<String, u32>) -> HashMap<String, u32> #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("Idna error: {0}")] + #[doc = "UTS #46 process has failed"] + #[error(transparent)] Idna(#[from] idna::Errors), - #[error("Database error: {0}")] + #[error(transparent)] Db(#[from] DbErr), } diff --git a/packages/backend-rs/src/service/antenna/check_hit.rs b/packages/backend-rs/src/service/antenna/check_hit.rs index fa9720f0cf..ed751e1a8c 100644 --- a/packages/backend-rs/src/service/antenna/check_hit.rs +++ b/packages/backend-rs/src/service/antenna/check_hit.rs @@ -8,9 +8,10 @@ use sea_orm::{prelude::*, QuerySelect}; #[derive(thiserror::Error, Debug)] pub enum AntennaCheckError { - #[error("Database error: {0}")] + #[doc = "database error"] + #[error(transparent)] Db(#[from] DbErr), - #[error("Cache error: {0}")] + #[error("Redis cache operation has failed")] Cache(#[from] cache::Error), } diff --git a/packages/backend-rs/src/service/antenna/process_new_note.rs b/packages/backend-rs/src/service/antenna/process_new_note.rs index a90ef11803..7e86fbd31f 100644 --- a/packages/backend-rs/src/service/antenna/process_new_note.rs +++ b/packages/backend-rs/src/service/antenna/process_new_note.rs @@ -15,19 +15,21 @@ use sea_orm::prelude::*; #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("Database error: {0}")] + #[doc = "database error"] + #[error(transparent)] Db(#[from] DbErr), - #[error("Cache error: {0}")] + #[error("Redis cache operation has failed")] Cache(#[from] cache::Error), - #[error("Redis error: {0}")] + #[error("failed to execute a Redis command")] Redis(#[from] RedisError), - #[error("Redis connection error: {0}")] + #[error("bad Redis connection")] RedisConn(#[from] RedisConnError), - #[error("Invalid ID: {0}")] + #[doc = "provided string is not a valid Firefish ID"] + #[error(transparent)] InvalidId(#[from] InvalidIdError), - #[error("Stream error: {0}")] + #[error("Redis stream operation has failed")] Stream(#[from] stream::Error), - #[error("Failed to check if the note should be added to antenna: {0}")] + #[error("failed to check if the note should be added to antenna")] AntennaCheck(#[from] AntennaCheckError), } diff --git a/packages/backend-rs/src/service/push_notification.rs b/packages/backend-rs/src/service/push_notification.rs index ccd83bf689..8bde9987d3 100644 --- a/packages/backend-rs/src/service/push_notification.rs +++ b/packages/backend-rs/src/service/push_notification.rs @@ -9,15 +9,17 @@ use web_push::*; #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("Database error: {0}")] + #[doc = "database error"] + #[error(transparent)] Db(#[from] DbErr), - #[error("Web Push error: {0}")] + #[error("web push has failed")] WebPush(#[from] WebPushError), - #[error("Failed to (de)serialize an object: {0}")] + #[error("failed to (de)serialize an object")] Serialize(#[from] serde_json::Error), - #[error("Invalid content: {0}")] + #[doc = "provided content is invalid"] + #[error("invalid content ({0})")] InvalidContent(String), - #[error("HTTP client aquisition error: {0}")] + #[error("failed to acquire an HTTP client")] HttpClient(#[from] http_client::Error), } diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index a028707d38..4a72fc7ec0 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -62,14 +62,14 @@ pub enum ChatEvent { #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("Redis error: {0}")] + #[error("failed to execute a Redis command")] Redis(#[from] RedisError), - #[error("Redis connection error: {0}")] + #[error("bad Redis connection")] RedisConn(#[from] RedisConnError), - #[error("Json (de)serialization error: {0}")] + #[error("failed to (de)serialize object")] Json(#[from] serde_json::Error), - #[error("Value error: {0}")] - Value(String), + #[error("invalid content")] + InvalidContent, } pub async fn publish_to_stream( @@ -104,7 +104,7 @@ pub async fn publish_to_stream( value.unwrap_or_else(|| "null".to_string()), ) } else { - value.ok_or(Error::Value("Invalid streaming message".to_string()))? + value.ok_or(Error::InvalidContent)? }; redis_conn() diff --git a/packages/backend-rs/src/util/http_client.rs b/packages/backend-rs/src/util/http_client.rs index 167f5c0198..3b56d57c6e 100644 --- a/packages/backend-rs/src/util/http_client.rs +++ b/packages/backend-rs/src/util/http_client.rs @@ -7,9 +7,9 @@ use std::time::Duration; #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("Isahc error: {0}")] + #[error("HTTP request failed")] Isahc(#[from] isahc::Error), - #[error("Url parse error: {0}")] + #[error("invalid URL")] UrlParse(#[from] isahc::http::uri::InvalidUri), } diff --git a/packages/backend-rs/src/util/id.rs b/packages/backend-rs/src/util/id.rs index 26c0e24d11..f61454d9c3 100644 --- a/packages/backend-rs/src/util/id.rs +++ b/packages/backend-rs/src/util/id.rs @@ -46,7 +46,8 @@ fn create_id(datetime: &NaiveDateTime) -> String { } #[derive(thiserror::Error, Debug)] -#[error("Invalid ID: {id}")] +#[doc = "Error type to indicate invalid Firefish ID"] +#[error("'{id}' is not a valid Firefish ID")] pub struct InvalidIdError { id: String, }