diff --git a/Cargo.lock b/Cargo.lock index 71bd6c8f6..9fb60b370 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -660,6 +660,15 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "backtrace-ext" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" +dependencies = [ + "backtrace", +] + [[package]] name = "base16ct" version = "0.2.0" @@ -994,6 +1003,7 @@ dependencies = [ "anstyle", "clap_lex", "strsim", + "terminal_size 0.3.0", ] [[package]] @@ -1023,33 +1033,6 @@ dependencies = [ "serde_shims", ] -[[package]] -name = "color-eyre" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" -dependencies = [ - "backtrace", - "color-spantrace", - "eyre", - "indenter", - "once_cell", - "owo-colors", - "tracing-error", -] - -[[package]] -name = "color-spantrace" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" -dependencies = [ - "once_cell", - "owo-colors", - "tracing-core", - "tracing-error", -] - [[package]] name = "colorchoice" version = "1.0.0" @@ -1945,16 +1928,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "eyre" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80f656be11ddf91bd709454d15d5bd896fbaf4cc3314e69349e4d1569f5b46cd" -dependencies = [ - "indenter", - "once_cell", -] - [[package]] name = "fallible-iterator" version = "0.2.0" @@ -2491,22 +2464,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "human-panic" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a79a67745be0cb8dd2771f03b24c2f25df98d5471fe7a595d668cfa2e6f843d" -dependencies = [ - "anstream", - "anstyle", - "backtrace", - "os_info", - "serde", - "serde_derive", - "toml 0.8.8", - "uuid", -] - [[package]] name = "humansize" version = "2.1.3" @@ -2647,12 +2604,6 @@ dependencies = [ "quote", ] -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - [[package]] name = "indexmap" version = "1.9.3" @@ -2720,6 +2671,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "is_ci" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb" + [[package]] name = "isahc" version = "1.7.2" @@ -2832,17 +2789,14 @@ dependencies = [ "bytes", "chrono", "clap", - "color-eyre", "const-oid", "deadpool-redis", "der", "diesel", "diesel-async", - "eyre", "futures-util", "headers", "http", - "human-panic", "hyper", "include_dir", "iso8601-timestamp", @@ -2875,6 +2829,7 @@ dependencies = [ "kitsune-util", "kitsune-webfinger", "metrics", + "miette", "mimalloc", "mime", "mime_guess", @@ -3001,12 +2956,12 @@ name = "kitsune-cli" version = "0.0.1-pre.4" dependencies = [ "clap", - "color-eyre", "diesel", "diesel-async", "dotenvy", "envy", "kitsune-db", + "miette", "serde", "speedy-uuid", "tokio", @@ -3018,7 +2973,7 @@ dependencies = [ name = "kitsune-config" version = "0.0.1-pre.4" dependencies = [ - "eyre", + "miette", "serde", "smol_str", "tokio", @@ -3054,6 +3009,7 @@ dependencies = [ "kitsune-language", "kitsune-test", "kitsune-type", + "miette", "num-derive", "num-traits 0.2.17", "serde", @@ -3077,6 +3033,7 @@ dependencies = [ "kitsune-db", "kitsune-url", "lettre", + "miette", "mrml", "scoped-futures", "speedy-uuid", @@ -3126,6 +3083,7 @@ dependencies = [ "globset", "kitsune-config", "kitsune-type", + "miette", "thiserror", "url", ] @@ -3173,7 +3131,6 @@ version = "0.0.1-pre.4" dependencies = [ "athena", "clap", - "color-eyre", "deadpool-redis", "kitsune-config", "kitsune-core", @@ -3186,6 +3143,7 @@ dependencies = [ "kitsune-retry-policies", "kitsune-service", "kitsune-url", + "miette", "mimalloc", "tokio", "toml 0.8.8", @@ -3201,15 +3159,14 @@ dependencies = [ "derive_more 1.0.0-beta.6", "diesel", "diesel-async", - "eyre", "futures-util", "kitsune-core", "kitsune-db", "kitsune-email", + "miette", "scoped-futures", "serde", "speedy-uuid", - "thiserror", "tracing", "typed-builder", ] @@ -3277,7 +3234,6 @@ name = "kitsune-observability" version = "0.0.1-pre.4" dependencies = [ "async-trait", - "eyre", "hyper", "kitsune-config", "kitsune-http-client", @@ -3285,6 +3241,7 @@ dependencies = [ "metrics-opentelemetry", "metrics-tracing-context", "metrics-util", + "miette", "opentelemetry", "opentelemetry-http", "opentelemetry-otlp", @@ -3305,6 +3262,7 @@ dependencies = [ "hyper", "kitsune-config", "kitsune-http-client", + "miette", "moka", "once_cell", "openidconnect", @@ -3337,6 +3295,7 @@ dependencies = [ "kitsune-db", "kitsune-language", "meilisearch-sdk", + "miette", "serde", "speedy-uuid", "strum", @@ -3357,7 +3316,6 @@ dependencies = [ "derive_builder", "diesel", "diesel-async", - "eyre", "futures-util", "garde", "hex-simd", @@ -3386,6 +3344,7 @@ dependencies = [ "kitsune-url", "kitsune-util", "kitsune-webfinger", + "miette", "mime", "password-hash", "pkcs8", @@ -3437,6 +3396,7 @@ dependencies = [ "http", "hyper", "kitsune-db", + "miette", "pin-project-lite", "redis", "scoped-futures", @@ -3934,6 +3894,38 @@ dependencies = [ "sketches-ddsketch", ] +[[package]] +name = "miette" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" +dependencies = [ + "backtrace", + "backtrace-ext", + "is-terminal", + "miette-derive", + "once_cell", + "owo-colors", + "supports-color", + "supports-hyperlinks", + "supports-unicode", + "terminal_size 0.1.17", + "textwrap", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "migrations_internals" version = "2.1.0" @@ -4435,17 +4427,6 @@ dependencies = [ "num-traits 0.2.17", ] -[[package]] -name = "os_info" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e" -dependencies = [ - "log", - "serde", - "winapi", -] - [[package]] name = "outref" version = "0.5.1" @@ -5881,6 +5862,12 @@ version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + [[package]] name = "smol_str" version = "0.2.0" @@ -6062,6 +6049,34 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +[[package]] +name = "supports-color" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89" +dependencies = [ + "is-terminal", + "is_ci", +] + +[[package]] +name = "supports-hyperlinks" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84231692eb0d4d41e4cdd0cabfdd2e6cd9e255e65f80c9aa7c98dd502b4233d" +dependencies = [ + "is-terminal", +] + +[[package]] +name = "supports-unicode" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b6c2cb240ab5dd21ed4906895ee23fe5a48acdbd15a3ce388e7b62a9b66baf7" +dependencies = [ + "is-terminal", +] + [[package]] name = "syn" version = "1.0.109" @@ -6120,6 +6135,37 @@ dependencies = [ "utf-8", ] +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "textwrap" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.50" @@ -6675,6 +6721,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + [[package]] name = "unicode-normalization" version = "0.1.22" @@ -6690,6 +6742,12 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + [[package]] name = "unicode-xid" version = "0.2.4" diff --git a/crates/kitsune-activitypub/src/error.rs b/crates/kitsune-activitypub/src/error.rs index 375b14049..c39884454 100644 --- a/crates/kitsune-activitypub/src/error.rs +++ b/crates/kitsune-activitypub/src/error.rs @@ -2,7 +2,10 @@ use diesel_async::pooled_connection::deadpool::PoolError as DatabasePoolError; use kitsune_core::error::BoxError; use kitsune_http_signatures::ring; use rsa::pkcs8::der; -use std::convert::Infallible; +use std::{ + convert::Infallible, + fmt::{Debug, Display}, +}; use thiserror::Error; pub type Result = std::result::Result; @@ -90,7 +93,7 @@ impl From for Error { impl From> for Error where - E: Into, + E: Into + Debug + Display, { fn from(value: kitsune_db::PoolError) -> Self { match value { diff --git a/crates/kitsune-config/Cargo.toml b/crates/kitsune-config/Cargo.toml index b459d35e5..f4506bd8d 100644 --- a/crates/kitsune-config/Cargo.toml +++ b/crates/kitsune-config/Cargo.toml @@ -5,7 +5,7 @@ edition.workspace = true version.workspace = true [dependencies] -eyre = "0.6.9" +miette = "5.10.0" serde = { version = "1.0.193", features = ["derive"] } smol_str = { version = "0.2.0", features = ["serde"] } tokio = { version = "1.34.0", features = ["fs"] } diff --git a/crates/kitsune-config/src/lib.rs b/crates/kitsune-config/src/lib.rs index 5d6d69e90..3a03e6370 100644 --- a/crates/kitsune-config/src/lib.rs +++ b/crates/kitsune-config/src/lib.rs @@ -13,6 +13,7 @@ pub mod server; pub mod storage; pub mod url; +use miette::{Context, IntoDiagnostic}; use serde::{Deserialize, Serialize}; use std::path::Path; use tokio::fs; @@ -36,11 +37,17 @@ pub struct Configuration { } impl Configuration { - pub async fn load

(path: P) -> eyre::Result + pub async fn load

(path: P) -> miette::Result where P: AsRef, { - let content = fs::read_to_string(path).await?; - toml::from_str(&content).map_err(eyre::Report::from) + let content = fs::read_to_string(path) + .await + .into_diagnostic() + .wrap_err("Couldn't read configuration file")?; + + toml::from_str(&content) + .into_diagnostic() + .wrap_err("Failed to parse configuration file") } } diff --git a/crates/kitsune-db/Cargo.toml b/crates/kitsune-db/Cargo.toml index ad12207b8..498f5610b 100644 --- a/crates/kitsune-db/Cargo.toml +++ b/crates/kitsune-db/Cargo.toml @@ -19,6 +19,7 @@ iso8601-timestamp = { version = "0.2.12", features = ["diesel-pg"] } kitsune-blocking = { path = "../kitsune-blocking" } kitsune-language = { path = "../kitsune-language" } kitsune-type = { path = "../kitsune-type" } +miette = "5.10.0" num-derive = "0.4.1" num-traits = "0.2.17" serde = { version = "1.0.193", features = ["derive"] } diff --git a/crates/kitsune-db/src/error.rs b/crates/kitsune-db/src/error.rs index a07900eb6..68ef51af4 100644 --- a/crates/kitsune-db/src/error.rs +++ b/crates/kitsune-db/src/error.rs @@ -1,6 +1,8 @@ use core::fmt; use diesel_async::pooled_connection::deadpool::PoolError; +use miette::Diagnostic; use std::error::Error as StdError; +use thiserror::Error; pub type BoxError = Box; pub type Result = std::result::Result; @@ -35,7 +37,7 @@ impl fmt::Display for IsoCodeConversionError { impl StdError for IsoCodeConversionError {} -#[derive(Debug, thiserror::Error)] +#[derive(Debug, Diagnostic, Error)] pub enum Error { #[error(transparent)] Blocking(#[from] kitsune_blocking::Error), diff --git a/crates/kitsune-db/src/pool.rs b/crates/kitsune-db/src/pool.rs index b7ae89841..baf597040 100644 --- a/crates/kitsune-db/src/pool.rs +++ b/crates/kitsune-db/src/pool.rs @@ -3,11 +3,18 @@ use diesel_async::{ scoped_futures::{ScopedBoxFuture, ScopedFutureWrapper}, AsyncConnection, AsyncPgConnection, }; -use std::future::Future; +use miette::Diagnostic; +use std::{ + fmt::{Debug, Display}, + future::Future, +}; use thiserror::Error; -#[derive(Debug, Error)] -pub enum PoolError { +#[derive(Debug, Diagnostic, Error)] +pub enum PoolError +where + E: Display + Debug, +{ #[error(transparent)] Pool(#[from] DeadpoolError), @@ -35,6 +42,7 @@ impl PgPool { for<'conn> F: FnOnce(&'conn mut Object) -> ScopedFutureWrapper<'conn, 'a, Fut>, Fut: Future>, + E: Display + Debug, { let mut conn = self.inner.get().await?; func(&mut conn).await.map_err(PoolError::User) @@ -48,7 +56,7 @@ impl PgPool { ) -> ScopedBoxFuture<'a, 'r, Result> + Send + 'a, - E: From + Send + 'a, + E: From + Debug + Display + Send + 'a, R: Send + 'a, { let mut conn = self.inner.get().await?; diff --git a/crates/kitsune-email/Cargo.toml b/crates/kitsune-email/Cargo.toml index 080728080..e06a8c401 100644 --- a/crates/kitsune-email/Cargo.toml +++ b/crates/kitsune-email/Cargo.toml @@ -23,6 +23,7 @@ lettre = { version = "0.11.2", default-features = false, features = [ "tokio1-rustls-tls", "tracing", ] } +miette = "5.10.0" mrml = { version = "2.0.0-rc4", default-features = false, features = [ "orderedmap", "parse", diff --git a/crates/kitsune-email/src/error.rs b/crates/kitsune-email/src/error.rs index 3fcb5d343..57c643403 100644 --- a/crates/kitsune-email/src/error.rs +++ b/crates/kitsune-email/src/error.rs @@ -1,11 +1,15 @@ use diesel_async::pooled_connection::deadpool::PoolError as DatabasePoolError; -use std::error::Error as StdError; +use miette::Diagnostic; +use std::{ + error::Error as StdError, + fmt::{Debug, Display}, +}; use thiserror::Error; pub type BoxError = Box; pub type Result = std::result::Result; -#[derive(Debug, Error)] +#[derive(Debug, Diagnostic, Error)] pub enum Error { #[error(transparent)] Address(#[from] lettre::address::AddressError), @@ -34,7 +38,7 @@ pub enum Error { impl From> for Error where - E: Into, + E: Into + Debug + Display, { fn from(value: kitsune_db::PoolError) -> Self { match value { diff --git a/crates/kitsune-embed/src/lib.rs b/crates/kitsune-embed/src/lib.rs index cd916555d..980dcbfba 100644 --- a/crates/kitsune-embed/src/lib.rs +++ b/crates/kitsune-embed/src/lib.rs @@ -13,6 +13,7 @@ use kitsune_http_client::Client as HttpClient; use once_cell::sync::Lazy; use scraper::{Html, Selector}; use smol_str::SmolStr; +use std::fmt::{Debug, Display}; use typed_builder::TypedBuilder; pub use embed_sdk; @@ -47,7 +48,7 @@ pub enum Error { impl From> for Error where - E: Into, + E: Into + Debug + Display, { fn from(value: kitsune_db::PoolError) -> Self { match value { diff --git a/crates/kitsune-federation-filter/Cargo.toml b/crates/kitsune-federation-filter/Cargo.toml index a799ecd33..46b2b7ab4 100644 --- a/crates/kitsune-federation-filter/Cargo.toml +++ b/crates/kitsune-federation-filter/Cargo.toml @@ -8,6 +8,7 @@ version.workspace = true globset = "0.4.14" kitsune-config = { path = "../kitsune-config" } kitsune-type = { path = "../kitsune-type" } +miette = "5.10.0" thiserror = "1.0.50" url = "2.5.0" diff --git a/crates/kitsune-federation-filter/src/error.rs b/crates/kitsune-federation-filter/src/error.rs index 99d0991e5..09dc106d6 100644 --- a/crates/kitsune-federation-filter/src/error.rs +++ b/crates/kitsune-federation-filter/src/error.rs @@ -1,8 +1,9 @@ +use miette::Diagnostic; use thiserror::Error; pub type Result = std::result::Result; -#[derive(Debug, Error)] +#[derive(Debug, Diagnostic, Error)] pub enum Error { #[error(transparent)] Glob(#[from] globset::Error), diff --git a/crates/kitsune-jobs/Cargo.toml b/crates/kitsune-jobs/Cargo.toml index 4614de527..8fa9da959 100644 --- a/crates/kitsune-jobs/Cargo.toml +++ b/crates/kitsune-jobs/Cargo.toml @@ -9,15 +9,14 @@ athena = { path = "../../lib/athena" } derive_more = { version = "1.0.0-beta.6", features = ["from"] } diesel = "2.1.4" diesel-async = "0.4.1" -eyre = "0.6.9" futures-util = "0.3.29" kitsune-core = { path = "../kitsune-core" } kitsune-db = { path = "../kitsune-db" } kitsune-email = { path = "../kitsune-email" } +miette = "5.10.0" scoped-futures = "0.1.3" serde = { version = "1.0.193", features = ["derive"] } speedy-uuid = { path = "../../lib/speedy-uuid" } -thiserror = "1.0.50" tracing = "0.1.40" typed-builder = "0.18.0" diff --git a/crates/kitsune-jobs/src/deliver/accept.rs b/crates/kitsune-jobs/src/deliver/accept.rs index d59c86758..ae53696b9 100644 --- a/crates/kitsune-jobs/src/deliver/accept.rs +++ b/crates/kitsune-jobs/src/deliver/accept.rs @@ -1,7 +1,4 @@ -use crate::{ - error::{Error, Result}, - JobRunnerContext, Runnable, -}; +use crate::{JobRunnerContext, Runnable}; use diesel::{OptionalExtension, QueryDsl}; use diesel_async::RunQueryDsl; use kitsune_core::traits::deliverer::Action; @@ -17,7 +14,7 @@ pub struct DeliverAccept { impl Runnable for DeliverAccept { type Context = JobRunnerContext; - type Error = eyre::Report; + type Error = miette::Report; #[instrument(skip_all, fields(follow_id = %self.follow_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { @@ -42,7 +39,7 @@ impl Runnable for DeliverAccept { ctx.deliverer .deliver(Action::AcceptFollow(follow)) .await - .map_err(Error::Delivery)?; + .map_err(|err| miette::Report::new_boxed(err.into()))?; Ok(()) } diff --git a/crates/kitsune-jobs/src/deliver/create.rs b/crates/kitsune-jobs/src/deliver/create.rs index e39210de0..3d157c1a2 100644 --- a/crates/kitsune-jobs/src/deliver/create.rs +++ b/crates/kitsune-jobs/src/deliver/create.rs @@ -1,4 +1,4 @@ -use crate::{error::Error, JobRunnerContext}; +use crate::JobRunnerContext; use athena::Runnable; use diesel::{OptionalExtension, QueryDsl, SelectableHelper}; use diesel_async::RunQueryDsl; @@ -15,7 +15,7 @@ pub struct DeliverCreate { impl Runnable for DeliverCreate { type Context = JobRunnerContext; - type Error = eyre::Report; + type Error = miette::Report; #[instrument(skip_all, fields(post_id = %self.post_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { @@ -41,7 +41,7 @@ impl Runnable for DeliverCreate { ctx.deliverer .deliver(Action::Create(post)) .await - .map_err(Error::Delivery)?; + .map_err(|err| miette::Report::new_boxed(err.into()))?; Ok(()) } diff --git a/crates/kitsune-jobs/src/deliver/delete.rs b/crates/kitsune-jobs/src/deliver/delete.rs index 5ab9ac481..3295c8c5d 100644 --- a/crates/kitsune-jobs/src/deliver/delete.rs +++ b/crates/kitsune-jobs/src/deliver/delete.rs @@ -1,4 +1,4 @@ -use crate::{error::Error, JobRunnerContext}; +use crate::JobRunnerContext; use athena::Runnable; use diesel::{OptionalExtension, QueryDsl, SelectableHelper}; use diesel_async::RunQueryDsl; @@ -15,7 +15,7 @@ pub struct DeliverDelete { impl Runnable for DeliverDelete { type Context = JobRunnerContext; - type Error = eyre::Report; + type Error = miette::Report; #[instrument(skip_all, fields(post_id = %self.post_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { @@ -41,7 +41,7 @@ impl Runnable for DeliverDelete { ctx.deliverer .deliver(Action::Delete(post)) .await - .map_err(Error::Delivery)?; + .map_err(|err| miette::Report::new_boxed(err.into()))?; ctx.db_pool .with_connection(|db_conn| { diff --git a/crates/kitsune-jobs/src/deliver/favourite.rs b/crates/kitsune-jobs/src/deliver/favourite.rs index 8bb407926..1dbc8d152 100644 --- a/crates/kitsune-jobs/src/deliver/favourite.rs +++ b/crates/kitsune-jobs/src/deliver/favourite.rs @@ -1,4 +1,4 @@ -use crate::{error::Error, JobRunnerContext}; +use crate::JobRunnerContext; use athena::Runnable; use diesel::QueryDsl; use diesel_async::RunQueryDsl; @@ -15,7 +15,7 @@ pub struct DeliverFavourite { impl Runnable for DeliverFavourite { type Context = JobRunnerContext; - type Error = eyre::Report; + type Error = miette::Report; #[instrument(skip_all, fields(favourite_id = %self.favourite_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { @@ -32,7 +32,7 @@ impl Runnable for DeliverFavourite { ctx.deliverer .deliver(Action::Favourite(favourite)) .await - .map_err(Error::Delivery)?; + .map_err(|err| miette::Report::new_boxed(err.into()))?; Ok(()) } diff --git a/crates/kitsune-jobs/src/deliver/follow.rs b/crates/kitsune-jobs/src/deliver/follow.rs index 30685e15f..b7e5312ce 100644 --- a/crates/kitsune-jobs/src/deliver/follow.rs +++ b/crates/kitsune-jobs/src/deliver/follow.rs @@ -1,4 +1,4 @@ -use crate::{error::Error, JobRunnerContext}; +use crate::JobRunnerContext; use athena::Runnable; use diesel::{OptionalExtension, QueryDsl}; use diesel_async::RunQueryDsl; @@ -15,7 +15,7 @@ pub struct DeliverFollow { impl Runnable for DeliverFollow { type Context = JobRunnerContext; - type Error = eyre::Report; + type Error = miette::Report; #[instrument(skip_all, fields(follow_id = %self.follow_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { @@ -40,7 +40,7 @@ impl Runnable for DeliverFollow { ctx.deliverer .deliver(Action::Follow(follow)) .await - .map_err(Error::Delivery)?; + .map_err(|err| miette::Report::new_boxed(err.into()))?; Ok(()) } diff --git a/crates/kitsune-jobs/src/deliver/reject.rs b/crates/kitsune-jobs/src/deliver/reject.rs index 6dd4ed510..0d0fb50b9 100644 --- a/crates/kitsune-jobs/src/deliver/reject.rs +++ b/crates/kitsune-jobs/src/deliver/reject.rs @@ -1,7 +1,4 @@ -use crate::{ - error::{Error, Result}, - JobRunnerContext, Runnable, -}; +use crate::{JobRunnerContext, Runnable}; use diesel::{OptionalExtension, QueryDsl}; use diesel_async::RunQueryDsl; use kitsune_core::traits::deliverer::Action; @@ -17,7 +14,7 @@ pub struct DeliverReject { impl Runnable for DeliverReject { type Context = JobRunnerContext; - type Error = eyre::Report; + type Error = miette::Report; #[instrument(skip_all, fields(follow_id = %self.follow_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { @@ -42,7 +39,7 @@ impl Runnable for DeliverReject { ctx.deliverer .deliver(Action::RejectFollow(follow)) .await - .map_err(Error::Delivery)?; + .map_err(|err| miette::Report::new_boxed(err.into()))?; ctx.db_pool .with_connection(|db_conn| { diff --git a/crates/kitsune-jobs/src/deliver/unfavourite.rs b/crates/kitsune-jobs/src/deliver/unfavourite.rs index 2bf502319..1cd9133ce 100644 --- a/crates/kitsune-jobs/src/deliver/unfavourite.rs +++ b/crates/kitsune-jobs/src/deliver/unfavourite.rs @@ -1,4 +1,4 @@ -use crate::{error::Error, JobRunnerContext}; +use crate::JobRunnerContext; use athena::Runnable; use diesel::{OptionalExtension, QueryDsl}; use diesel_async::RunQueryDsl; @@ -15,7 +15,7 @@ pub struct DeliverUnfavourite { impl Runnable for DeliverUnfavourite { type Context = JobRunnerContext; - type Error = eyre::Report; + type Error = miette::Report; #[instrument(skip_all, fields(favourite_id = %self.favourite_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { @@ -40,7 +40,7 @@ impl Runnable for DeliverUnfavourite { ctx.deliverer .deliver(Action::Unfavourite(favourite)) .await - .map_err(Error::Delivery)?; + .map_err(|err| miette::Report::new_boxed(err.into()))?; ctx.db_pool .with_connection(|db_conn| { diff --git a/crates/kitsune-jobs/src/deliver/unfollow.rs b/crates/kitsune-jobs/src/deliver/unfollow.rs index 431dcb682..26abbea60 100644 --- a/crates/kitsune-jobs/src/deliver/unfollow.rs +++ b/crates/kitsune-jobs/src/deliver/unfollow.rs @@ -1,4 +1,4 @@ -use crate::{error::Error, JobRunnerContext}; +use crate::JobRunnerContext; use athena::Runnable; use diesel::{OptionalExtension, QueryDsl}; use diesel_async::RunQueryDsl; @@ -15,7 +15,7 @@ pub struct DeliverUnfollow { impl Runnable for DeliverUnfollow { type Context = JobRunnerContext; - type Error = eyre::Report; + type Error = miette::Report; async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { let follow = ctx @@ -39,7 +39,7 @@ impl Runnable for DeliverUnfollow { ctx.deliverer .deliver(Action::Unfollow(follow)) .await - .map_err(Error::Delivery)?; + .map_err(|err| miette::Report::new_boxed(err.into()))?; ctx.db_pool .with_connection(|db_conn| { diff --git a/crates/kitsune-jobs/src/deliver/update.rs b/crates/kitsune-jobs/src/deliver/update.rs index 2f6e363f3..b6dddca7f 100644 --- a/crates/kitsune-jobs/src/deliver/update.rs +++ b/crates/kitsune-jobs/src/deliver/update.rs @@ -1,4 +1,4 @@ -use crate::{error::Error, JobRunnerContext}; +use crate::JobRunnerContext; use athena::Runnable; use diesel::{OptionalExtension, QueryDsl, SelectableHelper}; use diesel_async::RunQueryDsl; @@ -25,7 +25,7 @@ pub struct DeliverUpdate { impl Runnable for DeliverUpdate { type Context = JobRunnerContext; - type Error = eyre::Report; + type Error = miette::Report; async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { let action = match self.entity { @@ -78,7 +78,7 @@ impl Runnable for DeliverUpdate { ctx.deliverer .deliver(action) .await - .map_err(Error::Delivery)?; + .map_err(|err| miette::Report::new_boxed(err.into()))?; Ok(()) } diff --git a/crates/kitsune-jobs/src/error.rs b/crates/kitsune-jobs/src/error.rs deleted file mode 100644 index 4a66b92b0..000000000 --- a/crates/kitsune-jobs/src/error.rs +++ /dev/null @@ -1,10 +0,0 @@ -use kitsune_core::error::BoxError; -use thiserror::Error; - -pub type Result = std::result::Result; - -#[derive(Debug, Error)] -pub enum Error { - #[error(transparent)] - Delivery(BoxError), -} diff --git a/crates/kitsune-jobs/src/lib.rs b/crates/kitsune-jobs/src/lib.rs index 595c0664d..f9686e304 100644 --- a/crates/kitsune-jobs/src/lib.rs +++ b/crates/kitsune-jobs/src/lib.rs @@ -9,7 +9,6 @@ use self::{ }, mailing::confirmation::SendConfirmationMail, }; -use crate::error::Result; use athena::{JobContextRepository, Runnable}; use derive_more::From; use diesel::{ExpressionMethods, QueryDsl}; @@ -23,13 +22,13 @@ use kitsune_db::{ PgPool, }; use kitsune_email::MailingService; +use miette::IntoDiagnostic; use scoped_futures::ScopedFutureExt; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; use typed_builder::TypedBuilder; pub mod deliver; -pub mod error; pub mod mailing; pub struct Service { @@ -58,7 +57,7 @@ pub enum Job { impl Runnable for Job { type Context = JobRunnerContext; - type Error = eyre::Report; + type Error = miette::Report; async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { match self { @@ -90,7 +89,7 @@ impl KitsuneContextRepo { impl JobContextRepository for KitsuneContextRepo { type JobContext = Job; - type Error = eyre::Report; + type Error = miette::Report; type Stream = BoxStream<'static, Result<(Uuid, Self::JobContext), Self::Error>>; async fn fetch_context(&self, job_ids: I) -> Result @@ -109,7 +108,7 @@ impl JobContextRepository for KitsuneContextRepo { Ok(stream .map_ok(|ctx| (ctx.id, ctx.context.0)) - .map_err(eyre::Report::from) + .map(IntoDiagnostic::into_diagnostic) .boxed()) } diff --git a/crates/kitsune-jobs/src/mailing/confirmation.rs b/crates/kitsune-jobs/src/mailing/confirmation.rs index 66f091295..ad0b268a5 100644 --- a/crates/kitsune-jobs/src/mailing/confirmation.rs +++ b/crates/kitsune-jobs/src/mailing/confirmation.rs @@ -14,7 +14,7 @@ pub struct SendConfirmationMail { impl Runnable for SendConfirmationMail { type Context = JobRunnerContext; - type Error = eyre::Report; + type Error = miette::Report; async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { let mailing_service = &ctx.service.mailing; diff --git a/crates/kitsune-mastodon/src/error.rs b/crates/kitsune-mastodon/src/error.rs index 5f2e8a1e3..654adf78d 100644 --- a/crates/kitsune-mastodon/src/error.rs +++ b/crates/kitsune-mastodon/src/error.rs @@ -1,3 +1,5 @@ +use std::fmt::{Debug, Display}; + use diesel_async::pooled_connection::deadpool::PoolError as DeadpoolError; pub type Result = std::result::Result; @@ -22,7 +24,7 @@ pub enum Error { impl From> for Error where - E: Into, + E: Into + Debug + Display, { fn from(value: kitsune_db::PoolError) -> Self { match value { diff --git a/crates/kitsune-observability/Cargo.toml b/crates/kitsune-observability/Cargo.toml index 4d30ac61a..4e7c86e66 100644 --- a/crates/kitsune-observability/Cargo.toml +++ b/crates/kitsune-observability/Cargo.toml @@ -6,7 +6,6 @@ version.workspace = true [dependencies] async-trait = "0.1.74" -eyre = "0.6.9" hyper = { version = "0.14.27", default-features = false } kitsune-config = { path = "../kitsune-config" } kitsune-http-client = { path = "../kitsune-http-client" } @@ -14,6 +13,7 @@ metrics = "0.21.1" metrics-opentelemetry = { git = "https://github.com/aumetra/metrics-opentelemetry.git", rev = "d4762c6704ecac8bca8f14ee201ce83d652c382a" } metrics-tracing-context = "0.14.0" metrics-util = "0.15.1" +miette = "5.10.0" opentelemetry = { version = "0.21.0", default-features = false, features = [ "trace", ] } diff --git a/crates/kitsune-observability/src/lib.rs b/crates/kitsune-observability/src/lib.rs index 2d69f6ff7..513f4dcf3 100644 --- a/crates/kitsune-observability/src/lib.rs +++ b/crates/kitsune-observability/src/lib.rs @@ -1,10 +1,10 @@ use async_trait::async_trait; -use eyre::Context; use hyper::body::Body; use kitsune_config::{open_telemetry::Transport, Configuration}; use metrics_opentelemetry::OpenTelemetryRecorder; use metrics_tracing_context::{MetricsLayer, TracingContextLayer}; use metrics_util::layers::Layer as _; +use miette::{Context, IntoDiagnostic}; use opentelemetry::{ metrics::{noop::NoopMeterProvider, Meter, MeterProvider}, trace::{noop::NoopTracer, Tracer}, @@ -66,13 +66,18 @@ macro_rules! build_exporter { }}; } -fn initialise_logging(tracer: T) -> eyre::Result<()> +fn initialise_logging(tracer: T) -> miette::Result<()> where T: Tracer + PreSampledTracer + Send + Sync + 'static, { let env_filter = env::var("RUST_LOG") - .map_err(eyre::Report::from) - .and_then(|targets| targets.parse().context("Failed to parse RUST_LOG value")) + .into_diagnostic() + .and_then(|targets| { + targets + .parse() + .into_diagnostic() + .wrap_err("Failed to parse RUST_LOG value") + }) .unwrap_or_else(|_| Targets::default().with_default(LevelFilter::INFO)); let subscriber = Registry::default() @@ -83,20 +88,22 @@ where let subscriber = subscriber.with(MetricsLayer::new()); tracing::subscriber::set_global_default(subscriber) - .context("Couldn't install the global tracing subscriber")?; + .into_diagnostic() + .wrap_err("Couldn't install the global tracing subscriber")?; Ok(()) } -fn initialise_metrics(meter: Meter) -> eyre::Result<()> { +fn initialise_metrics(meter: Meter) -> miette::Result<()> { let recorder = TracingContextLayer::all().layer(OpenTelemetryRecorder::new(meter)); metrics::set_boxed_recorder(Box::new(recorder)) - .context("Couldn't install the global metrics recorder")?; + .into_diagnostic() + .wrap_err("Couldn't install the global metrics recorder")?; Ok(()) } -pub fn initialise(app_name: &'static str, config: &Configuration) -> eyre::Result<()> { +pub fn initialise(app_name: &'static str, config: &Configuration) -> miette::Result<()> { if let Some(ref opentelemetry_config) = config.opentelemetry { let http_client = HttpClientAdapter { inner: kitsune_http_client::Client::default(), @@ -112,7 +119,8 @@ pub fn initialise(app_name: &'static str, config: &Configuration) -> eyre::Resul let tracer = opentelemetry_otlp::new_pipeline() .tracing() .with_exporter(trace_exporter) - .install_batch(Tokio)?; + .install_batch(Tokio) + .into_diagnostic()?; initialise_logging(tracer)?; @@ -126,7 +134,8 @@ pub fn initialise(app_name: &'static str, config: &Configuration) -> eyre::Resul let meter_provider = opentelemetry_otlp::new_pipeline() .metrics(Tokio) .with_exporter(metrics_exporter) - .build()?; + .build() + .into_diagnostic()?; initialise_metrics(meter_provider.meter(app_name))?; } else { diff --git a/crates/kitsune-oidc/Cargo.toml b/crates/kitsune-oidc/Cargo.toml index f4dde627c..c33c1ded4 100644 --- a/crates/kitsune-oidc/Cargo.toml +++ b/crates/kitsune-oidc/Cargo.toml @@ -11,6 +11,7 @@ http = "0.2.11" hyper = "0.14.27" kitsune-config = { path = "../kitsune-config" } kitsune-http-client = { path = "../kitsune-http-client" } +miette = "5.10.0" moka = { version = "0.12.1", features = ["sync"] } once_cell = "1.18.0" openidconnect = { version = "3.4.0", default-features = false, features = [ diff --git a/crates/kitsune-oidc/src/error.rs b/crates/kitsune-oidc/src/error.rs index 318670161..e5f75e6f9 100644 --- a/crates/kitsune-oidc/src/error.rs +++ b/crates/kitsune-oidc/src/error.rs @@ -1,3 +1,4 @@ +use miette::Diagnostic; use openidconnect::{ core::CoreErrorResponseType, ClaimsVerificationError, DiscoveryError, RequestTokenError, SigningError, StandardErrorResponse, @@ -6,7 +7,7 @@ use thiserror::Error; pub type Result = std::result::Result; -#[derive(Debug, Error)] +#[derive(Debug, Diagnostic, Error)] pub enum Error { #[error(transparent)] ClaimsVerification(#[from] ClaimsVerificationError), diff --git a/crates/kitsune-search/Cargo.toml b/crates/kitsune-search/Cargo.toml index 114a9bd3a..230382ff4 100644 --- a/crates/kitsune-search/Cargo.toml +++ b/crates/kitsune-search/Cargo.toml @@ -15,6 +15,7 @@ enum_dispatch = "0.3.12" futures-util = "0.3.29" kitsune-db = { path = "../kitsune-db" } kitsune-language = { path = "../kitsune-language" } +miette = "5.10.0" serde = { version = "1.0.193", features = ["derive"] } speedy-uuid = { path = "../../lib/speedy-uuid" } strum = { version = "0.25.0", features = ["derive"] } diff --git a/crates/kitsune-search/src/error.rs b/crates/kitsune-search/src/error.rs index c726ddb24..64676e11a 100644 --- a/crates/kitsune-search/src/error.rs +++ b/crates/kitsune-search/src/error.rs @@ -1,6 +1,8 @@ +use miette::Diagnostic; +use std::fmt::{Debug, Display}; use thiserror::Error; -#[derive(Debug, Error)] +#[derive(Debug, Diagnostic, Error)] pub enum Error { #[error(transparent)] Database(#[from] diesel::result::Error), @@ -15,7 +17,7 @@ pub enum Error { impl From> for Error where - E: Into, + E: Into + Debug + Display, { fn from(value: kitsune_db::PoolError) -> Self { match value { diff --git a/crates/kitsune-service/Cargo.toml b/crates/kitsune-service/Cargo.toml index 71db21586..9a3f7375f 100644 --- a/crates/kitsune-service/Cargo.toml +++ b/crates/kitsune-service/Cargo.toml @@ -14,7 +14,6 @@ deadpool-redis = "0.13.0" derive_builder = "0.12.0" diesel = "2.1.4" diesel-async = "0.4.1" -eyre = "0.6.9" futures-util = "0.3.29" garde = { version = "0.16.3", default-features = false, features = [ "derive", @@ -43,6 +42,7 @@ kitsune-search = { path = "../kitsune-search" } kitsune-storage = { path = "../kitsune-storage" } kitsune-url = { path = "../kitsune-url" } kitsune-util = { path = "../kitsune-util" } +miette = "5.10.0" mime = "0.3.17" password-hash = { version = "0.5.0", features = ["std"] } pkcs8 = "0.10.2" diff --git a/crates/kitsune-service/src/attachment.rs b/crates/kitsune-service/src/attachment.rs index fe6ba891d..582cdceac 100644 --- a/crates/kitsune-service/src/attachment.rs +++ b/crates/kitsune-service/src/attachment.rs @@ -280,7 +280,7 @@ mod test { let account_id = db_pool .with_connection(|db_conn| { - async move { Ok::<_, eyre::Report>(prepare_db(db_conn).await) }.scoped() + async move { Ok::<_, miette::Report>(prepare_db(db_conn).await) }.scoped() }) .await .unwrap(); diff --git a/crates/kitsune-service/src/error.rs b/crates/kitsune-service/src/error.rs index 8b0dc9e83..e797b23a3 100644 --- a/crates/kitsune-service/src/error.rs +++ b/crates/kitsune-service/src/error.rs @@ -1,5 +1,8 @@ use kitsune_http_signatures::ring; -use std::error::Error as StdError; +use std::{ + error::Error as StdError, + fmt::{Debug, Display}, +}; use thiserror::Error; pub type BoxError = Box; @@ -133,7 +136,7 @@ pub enum Error { impl From> for Error where - E: Into, + E: Into + Debug + Display, { fn from(value: kitsune_db::PoolError) -> Self { match value { diff --git a/crates/kitsune-service/src/prepare.rs b/crates/kitsune-service/src/prepare.rs index dbf7d3a9e..54fdbfa85 100644 --- a/crates/kitsune-service/src/prepare.rs +++ b/crates/kitsune-service/src/prepare.rs @@ -1,4 +1,3 @@ -use eyre::Context; use kitsune_cache::{ArcCache, InMemoryCache, NoopCache, RedisCache}; use kitsune_captcha::AnyCaptcha; use kitsune_captcha::{hcaptcha::Captcha as HCaptcha, mcaptcha::Captcha as MCaptcha}; @@ -13,6 +12,7 @@ use kitsune_messaging::{ }; use kitsune_search::{AnySearchBackend, NoopSearchService, SqlSearchService}; use kitsune_storage::{fs::Storage as FsStorage, s3::Storage as S3Storage, AnyStorageBackend}; +use miette::{Context, IntoDiagnostic}; use serde::{de::DeserializeOwned, Serialize}; use std::{ fmt::Display, @@ -70,7 +70,7 @@ pub fn captcha(config: &captcha::Configuration) -> AnyCaptcha { } } -pub fn storage(config: &storage::Configuration) -> eyre::Result { +pub fn storage(config: &storage::Configuration) -> miette::Result { let storage = match config { storage::Configuration::Fs(ref fs_config) => { FsStorage::new(fs_config.upload_dir.as_str().into()).into() @@ -87,11 +87,12 @@ pub fn storage(config: &storage::Configuration) -> eyre::Result eyre::Result eyre::Result>> { +) -> miette::Result>> { let transport_builder = if config.starttls { - AsyncSmtpTransport::::starttls_relay(config.host.as_str())? + AsyncSmtpTransport::::starttls_relay(config.host.as_str()) } else { - AsyncSmtpTransport::::relay(config.host.as_str())? - }; + AsyncSmtpTransport::::relay(config.host.as_str()) + } + .into_diagnostic()?; let transport = transport_builder .credentials((config.username.as_str(), config.password.as_str()).into()) @@ -115,11 +117,11 @@ pub fn mail_sender( Ok(MailSender::builder() .backend(transport) - .from_mailbox(Mailbox::from_str(config.from_address.as_str())?) + .from_mailbox(Mailbox::from_str(config.from_address.as_str()).into_diagnostic()?) .build()) } -pub async fn messaging(config: &messaging::Configuration) -> eyre::Result { +pub async fn messaging(config: &messaging::Configuration) -> miette::Result { let backend = match config { messaging::Configuration::InProcess => { MessagingHub::new(TokioBroadcastMessagingBackend::default()) @@ -127,7 +129,8 @@ pub async fn messaging(config: &messaging::Configuration) -> eyre::Result { let redis_messaging_backend = RedisMessagingBackend::new(&redis_config.url) .await - .context("Failed to initialise Redis messaging backend")?; + .into_diagnostic() + .wrap_err("Failed to initialise Redis messaging backend")?; MessagingHub::new(redis_messaging_backend) } @@ -140,7 +143,7 @@ pub async fn messaging(config: &messaging::Configuration) -> eyre::Result eyre::Result { +) -> miette::Result { let service = match search_config { search::Configuration::Meilisearch(_config) => { #[cfg(not(feature = "meilisearch"))] @@ -150,7 +153,7 @@ pub async fn search( #[allow(clippy::used_underscore_binding)] kitsune_search::MeiliSearchService::new(&_config.instance_url, &_config.api_key) .await - .context("Failed to connect to Meilisearch")? + .wrap_err("Failed to connect to Meilisearch")? .into() } search::Configuration::Sql => SqlSearchService::new(db_pool.clone()).into(), diff --git a/crates/kitsune-test/Cargo.toml b/crates/kitsune-test/Cargo.toml index 7b95d8c03..6f4518822 100644 --- a/crates/kitsune-test/Cargo.toml +++ b/crates/kitsune-test/Cargo.toml @@ -12,6 +12,7 @@ futures-util = "0.3.29" http = "0.2.11" hyper = "0.14.27" kitsune-db = { path = "../kitsune-db" } +miette = "5.10.0" pin-project-lite = "0.2.13" redis = "0.23.3" scoped-futures = "0.1.3" diff --git a/kitsune-cli/Cargo.toml b/kitsune-cli/Cargo.toml index 0e05e0d3b..5f77d4061 100644 --- a/kitsune-cli/Cargo.toml +++ b/kitsune-cli/Cargo.toml @@ -12,13 +12,13 @@ license = false eula = false [dependencies] -clap = { version = "4.4.10", features = ["derive"] } -color-eyre = "0.6.2" +clap = { version = "4.4.10", features = ["derive", "wrap_help"] } diesel = "2.1.4" diesel-async = "0.4.1" dotenvy = "0.15.7" envy = "0.4.2" kitsune-db = { path = "../crates/kitsune-db" } +miette = { version = "5.10.0", features = ["fancy"] } serde = { version = "1.0.193", features = ["derive"] } speedy-uuid = { path = "../lib/speedy-uuid" } tokio = { version = "1.34.0", features = ["full"] } diff --git a/kitsune-cli/src/main.rs b/kitsune-cli/src/main.rs index 3811ec1f1..61e71555e 100644 --- a/kitsune-cli/src/main.rs +++ b/kitsune-cli/src/main.rs @@ -1,7 +1,7 @@ use self::{config::Configuration, role::RoleSubcommand}; use clap::{Parser, Subcommand}; -use color_eyre::eyre::{self, Result}; use diesel_async::scoped_futures::ScopedFutureExt; +use miette::{IntoDiagnostic, Result}; mod config; mod role; @@ -23,11 +23,11 @@ struct App { #[tokio::main] async fn main() -> Result<()> { - color_eyre::install()?; + miette::set_panic_hook(); dotenvy::dotenv().ok(); tracing_subscriber::fmt::init(); - let config: Configuration = envy::from_env()?; + let config: Configuration = envy::from_env().into_diagnostic()?; let db_conn = kitsune_db::connect(&config.database_url, 1).await?; let cmd = App::parse(); @@ -38,7 +38,7 @@ async fn main() -> Result<()> { AppSubcommand::Role(cmd) => self::role::handle(cmd, db_conn).await?, } - Ok::<_, eyre::Report>(()) + Ok::<_, miette::Report>(()) } .scoped() }) diff --git a/kitsune-cli/src/role.rs b/kitsune-cli/src/role.rs index 4eeca7f30..3595b39ed 100644 --- a/kitsune-cli/src/role.rs +++ b/kitsune-cli/src/role.rs @@ -1,4 +1,3 @@ -use crate::Result; use clap::{Args, Subcommand, ValueEnum}; use diesel::{BelongingToDsl, BoolExpressionMethods, ExpressionMethods, QueryDsl}; use diesel_async::{AsyncPgConnection, RunQueryDsl}; @@ -6,6 +5,7 @@ use kitsune_db::model::{ user::User, user_role::{NewUserRole, Role as DbRole, UserRole}, }; +use miette::{IntoDiagnostic, Result}; use speedy_uuid::Uuid; #[derive(Subcommand)] @@ -57,7 +57,8 @@ async fn add_role(db_conn: &mut AsyncPgConnection, username_str: &str, role: Rol let user = users .filter(username.eq(username_str)) .first::(db_conn) - .await?; + .await + .into_diagnostic()?; let new_role = NewUserRole { id: Uuid::now_v7(), @@ -68,7 +69,8 @@ async fn add_role(db_conn: &mut AsyncPgConnection, username_str: &str, role: Rol diesel::insert_into(users_roles::table) .values(&new_role) .execute(db_conn) - .await?; + .await + .into_diagnostic()?; Ok(()) } @@ -79,11 +81,13 @@ async fn list_roles(db_conn: &mut AsyncPgConnection, username_str: &str) -> Resu let user: User = users::table .filter(users::username.eq(username_str)) .first(db_conn) - .await?; + .await + .into_diagnostic()?; let roles = UserRole::belonging_to(&user) .load::(db_conn) - .await?; + .await + .into_diagnostic()?; println!("User \"{username_str}\" has the following roles:"); for role in roles { @@ -103,7 +107,8 @@ async fn remove_role( let user = users::table .filter(users::username.eq(username_str)) .first::(db_conn) - .await?; + .await + .into_diagnostic()?; diesel::delete( users_roles::table.filter( @@ -113,7 +118,8 @@ async fn remove_role( ), ) .execute(db_conn) - .await?; + .await + .into_diagnostic()?; Ok(()) } diff --git a/kitsune-job-runner/Cargo.toml b/kitsune-job-runner/Cargo.toml index 3870dfa87..7c9e58673 100644 --- a/kitsune-job-runner/Cargo.toml +++ b/kitsune-job-runner/Cargo.toml @@ -12,8 +12,7 @@ eula = false [dependencies] athena = { path = "../lib/athena" } -clap = { version = "4.4.10", features = ["derive"] } -color-eyre = "0.6.2" +clap = { version = "4.4.10", features = ["derive", "wrap_help"] } deadpool-redis = "0.13.0" kitsune-config = { path = "../crates/kitsune-config" } kitsune-core = { path = "../crates/kitsune-core" } @@ -26,6 +25,7 @@ kitsune-observability = { path = "../crates/kitsune-observability" } kitsune-retry-policies = { path = "../crates/kitsune-retry-policies" } kitsune-service = { path = "../crates/kitsune-service" } kitsune-url = { path = "../crates/kitsune-url" } +miette = { version = "5.10.0", features = ["fancy"] } mimalloc = "0.1.39" tokio = { version = "1.34.0", features = ["full"] } toml = "0.8.8" diff --git a/kitsune-job-runner/src/main.rs b/kitsune-job-runner/src/main.rs index d89fb8008..ecddfad18 100644 --- a/kitsune-job-runner/src/main.rs +++ b/kitsune-job-runner/src/main.rs @@ -1,13 +1,12 @@ use clap::Parser; -use color_eyre::eyre; use kitsune_config::Configuration; use kitsune_core::consts::VERSION; use kitsune_federation_filter::FederationFilter; use kitsune_job_runner::JobDispatcherState; use kitsune_service::{attachment::AttachmentService, prepare}; use kitsune_url::UrlService; +use miette::IntoDiagnostic; use std::path::PathBuf; -use tokio::fs; #[global_allocator] static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; @@ -22,12 +21,11 @@ struct Args { } #[tokio::main] -async fn main() -> eyre::Result<()> { - color_eyre::install()?; +async fn main() -> miette::Result<()> { + miette::set_panic_hook(); let args = Args::parse(); - let raw_config = fs::read_to_string(args.config).await?; - let config: Configuration = toml::from_str(&raw_config)?; + let config = Configuration::load(args.config).await?; kitsune_observability::initialise(env!("CARGO_PKG_NAME"), &config)?; @@ -36,7 +34,8 @@ async fn main() -> eyre::Result<()> { config.database.max_connections as usize, ) .await?; - let job_queue = kitsune_job_runner::prepare_job_queue(db_pool.clone(), &config.job_queue)?; + let job_queue = kitsune_job_runner::prepare_job_queue(db_pool.clone(), &config.job_queue) + .into_diagnostic()?; let url_service = UrlService::builder() .domain(config.url.domain) diff --git a/kitsune/Cargo.toml b/kitsune/Cargo.toml index 7ab1393df..f0ddc94d1 100644 --- a/kitsune/Cargo.toml +++ b/kitsune/Cargo.toml @@ -31,17 +31,14 @@ axum-extra = { version = "0.8.0", features = [ axum-flash = "0.7.0" bytes = "1.5.0" chrono = { version = "0.4.31", default-features = false } -clap = { version = "4.4.10", features = ["derive"] } -color-eyre = "0.6.2" +clap = { version = "4.4.10", features = ["derive", "wrap_help"] } const-oid = { version = "0.9.5", features = ["db"] } der = { version = "0.7.8", features = ["std"] } diesel = "2.1.4" diesel-async = "0.4.1" -eyre = "0.6.9" futures-util = "0.3.29" headers = "0.3.9" http = "0.2.11" -human-panic = "1.2.2" hyper = { version = "0.14.27", features = ["deprecated"] } include_dir = "0.7.3" iso8601-timestamp = "0.2.12" @@ -70,6 +67,7 @@ kitsune-url = { path = "../crates/kitsune-url" } kitsune-util = { path = "../crates/kitsune-util" } kitsune-webfinger = { path = "../crates/kitsune-webfinger" } metrics = "0.21.1" +miette = { version = "5.10.0", features = ["fancy"] } mimalloc = "0.1.39" mime = "0.3.17" mime_guess = { version = "2.0.4", default-features = false } diff --git a/kitsune/src/error.rs b/kitsune/src/error.rs index aa216a6a9..f0de0a51d 100644 --- a/kitsune/src/error.rs +++ b/kitsune/src/error.rs @@ -7,7 +7,10 @@ use axum::{ use http::StatusCode; use kitsune_core::error::{BoxError, HttpError}; use kitsune_service::error::{Error as ServiceError, PostError}; -use std::str::ParseBoolError; +use std::{ + fmt::{Debug, Display}, + str::ParseBoolError, +}; use thiserror::Error; pub type Result = std::result::Result; @@ -110,7 +113,7 @@ pub enum OAuth2Error { impl From> for Error where - E: Into, + E: Into + Debug + Display, { fn from(value: kitsune_db::PoolError) -> Self { match value { diff --git a/kitsune/src/http/handler/well_known/webfinger.rs b/kitsune/src/http/handler/well_known/webfinger.rs index aec8edcd6..2396e8b41 100644 --- a/kitsune/src/http/handler/well_known/webfinger.rs +++ b/kitsune/src/http/handler/well_known/webfinger.rs @@ -167,7 +167,7 @@ mod tests { redis_test(|redis_pool| async move { let account_id = db_pool .with_connection(|db_conn| { - async move { Ok::<_, eyre::Report>(prepare_db(db_conn).await) }.scoped() + async move { Ok::<_, miette::Report>(prepare_db(db_conn).await) }.scoped() }) .await .unwrap(); @@ -237,7 +237,7 @@ mod tests { .with_connection(|db_conn| { async move { prepare_db(db_conn).await; - Ok::<_, eyre::Report>(()) + Ok::<_, miette::Report>(()) } .scoped() }) diff --git a/kitsune/src/http/mod.rs b/kitsune/src/http/mod.rs index 08648ed7b..1faa51e09 100644 --- a/kitsune/src/http/mod.rs +++ b/kitsune/src/http/mod.rs @@ -6,8 +6,8 @@ use self::{ }; use crate::state::Zustand; use axum::{extract::DefaultBodyLimit, Router}; -use eyre::Context; use kitsune_config::server; +use miette::{Context, IntoDiagnostic}; use std::time::Duration; use tower_http::{ catch_panic::CatchPanicLayer, @@ -34,7 +34,7 @@ pub mod extractor; pub fn create_router( state: Zustand, server_config: &server::Configuration, -) -> eyre::Result { +) -> miette::Result { let frontend_dir = &server_config.frontend_dir; let frontend_index_path = { let mut tmp = frontend_dir.to_string(); @@ -82,7 +82,8 @@ pub fn create_router( if !server_config.clacks_overhead.is_empty() { let clacks_overhead_layer = XClacksOverheadLayer::new(server_config.clacks_overhead.iter().map(AsRef::as_ref)) - .context("Invalid clacks overhead values")?; + .into_diagnostic() + .wrap_err("Invalid clacks overhead values")?; router = router.layer(clacks_overhead_layer); } @@ -99,11 +100,13 @@ pub fn create_router( } #[instrument(skip_all, fields(port = %server_config.port))] -pub async fn run(state: Zustand, server_config: server::Configuration) -> eyre::Result<()> { +pub async fn run(state: Zustand, server_config: server::Configuration) -> miette::Result<()> { let router = create_router(state, &server_config)?; + axum::Server::bind(&([0, 0, 0, 0], server_config.port).into()) .serve(router.into_make_service()) - .await?; + .await + .into_diagnostic()?; Ok(()) } diff --git a/kitsune/src/lib.rs b/kitsune/src/lib.rs index c62b43c57..047107094 100644 --- a/kitsune/src/lib.rs +++ b/kitsune/src/lib.rs @@ -50,7 +50,7 @@ pub async fn initialise_state( config: &Configuration, db_pool: PgPool, job_queue: JobQueue, -) -> eyre::Result { +) -> miette::Result { let messaging_hub = prepare::messaging(&config.messaging).await?; let status_event_emitter = messaging_hub.emitter("event.status".into()); diff --git a/kitsune/src/main.rs b/kitsune/src/main.rs index e78a4da8e..71ad0429e 100644 --- a/kitsune/src/main.rs +++ b/kitsune/src/main.rs @@ -2,53 +2,17 @@ extern crate tracing; use clap::Parser; -use color_eyre::{config::HookBuilder, Help}; -use eyre::Context; use kitsune::consts::STARTUP_FIGLET; use kitsune_config::Configuration; use kitsune_core::consts::VERSION; use kitsune_job_runner::JobDispatcherState; -use std::{ - borrow::Cow, - env, future, - panic::{self, PanicInfo}, - path::PathBuf, -}; +use miette::{Context, IntoDiagnostic, MietteDiagnostic}; +use std::{env, future, path::PathBuf}; use url::Url; #[global_allocator] static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; -fn install_handlers() -> eyre::Result<()> { - let (eyre_panic_hook, eyre_hook) = HookBuilder::new().into_hooks(); - let metadata = human_panic::Metadata { - version: Cow::Borrowed(VERSION), - ..human_panic::metadata!() - }; - - let eyre_panic_hook = move |panic_info: &PanicInfo<'_>| { - eprintln!("{}", eyre_panic_hook.panic_report(panic_info)); - }; - let human_panic_hook = move |panic_info: &PanicInfo<'_>| { - let path = human_panic::handle_dump(&metadata, panic_info); - human_panic::print_msg(path, &metadata).ok(); - }; - - eyre_hook.install()?; - panic::set_hook(Box::new(move |panic_info| { - let hook: &(dyn Fn(&PanicInfo<'_>) + Send + Sync) = - if cfg!(debug_assertions) || env::var("RUST_BACKTRACE").is_ok() { - &eyre_panic_hook - } else { - &human_panic_hook - }; - - hook(panic_info); - })); - - Ok(()) -} - fn postgres_url_diagnostics(db_url: &str) -> String { let url = match Url::parse(db_url) { Ok(url) => url, @@ -79,7 +43,7 @@ struct Args { config: PathBuf, } -async fn boot() -> eyre::Result<()> { +async fn boot() -> miette::Result<()> { println!("{STARTUP_FIGLET}"); let args = Args::parse(); @@ -91,11 +55,16 @@ async fn boot() -> eyre::Result<()> { config.database.max_connections as usize, ) .await - .context("Failed to connect to and migrate the database") - .with_suggestion(|| postgres_url_diagnostics(&config.database.url))?; + .wrap_err("Failed to connect to and migrate the database") + .map_err(|err| { + MietteDiagnostic::new(err.to_string()) + .with_help(postgres_url_diagnostics(&config.database.url)) + })?; let job_queue = kitsune_job_runner::prepare_job_queue(conn.clone(), &config.job_queue) - .context("Failed to connect to the Redis instance for the job scheduler")?; + .into_diagnostic() + .wrap_err("Failed to connect to the Redis instance for the job scheduler")?; + let state = kitsune::initialise_state(&config, conn, job_queue.clone()).await?; tokio::spawn({ @@ -127,13 +96,14 @@ async fn boot() -> eyre::Result<()> { Ok(()) } -fn main() -> eyre::Result<()> { - install_handlers()?; +fn main() -> miette::Result<()> { + miette::set_panic_hook(); let runtime = tokio::runtime::Builder::new_multi_thread() .enable_all() .thread_stack_size(4 * 1024 * 1024) // Set the stack size to 4MiB - .build()?; + .build() + .into_diagnostic()?; runtime.block_on(boot()) }