diff --git a/Cargo.lock b/Cargo.lock index c7799fe28..66a577b85 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1392,6 +1392,33 @@ dependencies = [ "cc", ] +[[package]] +name = "color-eyre" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors 3.5.0", + "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 3.5.0", + "tracing-core", + "tracing-error", +] + [[package]] name = "colorchoice" version = "1.0.0" @@ -2393,6 +2420,16 @@ dependencies = [ "wit-bindgen", ] +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -3347,6 +3384,12 @@ dependencies = [ "miniz_oxide 0.5.4", ] +[[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" @@ -3643,7 +3686,6 @@ dependencies = [ "kitsune-wasm-mrf", "kitsune-webfinger", "metrics", - "miette", "mimalloc", "mime", "mime_guess", @@ -3762,13 +3804,13 @@ name = "kitsune-cli" version = "0.0.1-pre.6" dependencies = [ "clap", + "color-eyre", "diesel", "diesel-async", "dotenvy", "envy", "kitsune-config", "kitsune-db", - "miette", "serde", "speedy-uuid", "tokio", @@ -3780,8 +3822,8 @@ dependencies = [ name = "kitsune-config" version = "0.0.1-pre.6" dependencies = [ + "eyre", "isolang", - "miette", "serde", "smol_str", "tokio", @@ -3794,6 +3836,7 @@ version = "0.0.1-pre.6" dependencies = [ "async-trait", "const_format", + "eyre", "http 1.1.0", "kitsune-db", "kitsune-messaging", @@ -3819,7 +3862,6 @@ dependencies = [ "kitsune-language", "kitsune-test", "kitsune-type", - "miette", "num-derive", "num-traits", "rustls 0.23.4", @@ -3847,9 +3889,7 @@ dependencies = [ "kitsune-db", "kitsune-url", "lettre", - "miette", "mrml", - "scoped-futures", "speedy-uuid", "thiserror", "typed-builder", @@ -3899,7 +3939,6 @@ dependencies = [ "globset", "kitsune-config", "kitsune-type", - "miette", "thiserror", "url", ] @@ -3945,7 +3984,6 @@ dependencies = [ "kitsune-service", "kitsune-url", "kitsune-wasm-mrf", - "miette", "mimalloc", "multiplex-pool", "redis", @@ -3962,11 +4000,11 @@ 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", @@ -4038,6 +4076,7 @@ name = "kitsune-observability" version = "0.0.1-pre.6" dependencies = [ "async-trait", + "eyre", "http-body-util", "http-compat", "hyper 1.2.0", @@ -4047,7 +4086,6 @@ dependencies = [ "metrics-opentelemetry", "metrics-tracing-context", "metrics-util", - "miette", "opentelemetry", "opentelemetry-http", "opentelemetry-otlp", @@ -4067,7 +4105,6 @@ dependencies = [ "http-compat", "kitsune-config", "kitsune-http-client", - "miette", "moka", "multiplex-pool", "once_cell", @@ -4120,7 +4157,6 @@ dependencies = [ "kitsune-db", "kitsune-language", "meilisearch-sdk", - "miette", "serde", "speedy-uuid", "strum", @@ -4142,6 +4178,7 @@ dependencies = [ "derive_builder", "diesel", "diesel-async", + "eyre", "futures-util", "garde", "hex-simd", @@ -4169,7 +4206,6 @@ dependencies = [ "kitsune-url", "kitsune-util", "kitsune-webfinger", - "miette", "mime", "multiplex-pool", "password-hash", @@ -4277,12 +4313,12 @@ name = "kitsune-wasm-mrf" version = "0.0.1-pre.6" dependencies = [ "async-trait", + "color-eyre", "derive_more 1.0.0-beta.6", "enum_dispatch", "futures-util", "kitsune-config", "kitsune-type", - "miette", "mrf-manifest", "multiplex-pool", "redis", @@ -4307,6 +4343,7 @@ version = "0.0.1-pre.6" dependencies = [ "async-trait", "autometrics", + "eyre", "futures-util", "http 1.1.0", "http-body-util", @@ -4838,7 +4875,7 @@ dependencies = [ "backtrace-ext", "cfg-if", "miette-derive", - "owo-colors", + "owo-colors 4.0.0", "supports-color", "supports-hyperlinks", "supports-unicode", @@ -4976,7 +5013,6 @@ version = "0.0.1-pre.6" dependencies = [ "insta", "leb128", - "miette", "olpc-cjson", "schemars", "semver", @@ -4993,7 +5029,7 @@ name = "mrf-tool" version = "0.0.1-pre.6" dependencies = [ "clap", - "miette", + "color-eyre", "mrf-manifest", "serde_json", "wasmparser 0.202.0", @@ -5441,6 +5477,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + [[package]] name = "owo-colors" version = "4.0.0" diff --git a/crates/kitsune-config/Cargo.toml b/crates/kitsune-config/Cargo.toml index 924ab1016..158fa4f43 100644 --- a/crates/kitsune-config/Cargo.toml +++ b/crates/kitsune-config/Cargo.toml @@ -6,8 +6,8 @@ version.workspace = true license.workspace = true [dependencies] +eyre = "0.6.12" isolang = { version = "2.4.0", features = ["serde"] } -miette = "7.2.0" serde = { version = "1.0.197", features = ["derive"] } smol_str = { version = "0.2.1", features = ["serde"] } tokio = { version = "1.37.0", features = ["fs"] } diff --git a/crates/kitsune-config/src/lib.rs b/crates/kitsune-config/src/lib.rs index 1b6100026..71dbcb50c 100644 --- a/crates/kitsune-config/src/lib.rs +++ b/crates/kitsune-config/src/lib.rs @@ -15,7 +15,7 @@ pub mod server; pub mod storage; pub mod url; -use miette::{Context, IntoDiagnostic}; +use eyre::{Result, WrapErr}; use serde::{Deserialize, Serialize}; use std::path::Path; use tokio::fs; @@ -41,17 +41,14 @@ pub struct Configuration { } impl Configuration { - pub async fn load

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

(path: P) -> Result where P: AsRef, { 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") + toml::from_str(&content).wrap_err("Failed to parse configuration file") } } diff --git a/crates/kitsune-core/Cargo.toml b/crates/kitsune-core/Cargo.toml index b0581b58a..ad8fa39bc 100644 --- a/crates/kitsune-core/Cargo.toml +++ b/crates/kitsune-core/Cargo.toml @@ -9,6 +9,7 @@ build = "build.rs" [dependencies] async-trait = "0.1.79" const_format = "0.2.32" +eyre = "0.6.12" http = "1.1.0" kitsune-db = { path = "../kitsune-db" } kitsune-messaging = { path = "../kitsune-messaging" } diff --git a/crates/kitsune-core/src/error.rs b/crates/kitsune-core/src/error.rs index a6e423c48..093083db4 100644 --- a/crates/kitsune-core/src/error.rs +++ b/crates/kitsune-core/src/error.rs @@ -1,10 +1,7 @@ use http::StatusCode; use std::borrow::Cow; -use std::error::Error as StdError; use thiserror::Error; -pub type BoxError = Box; - macro_rules! http_error { ($($variant_name:ident => $status_code:path),*$(,)?) => { #[derive(Debug, Error)] diff --git a/crates/kitsune-core/src/traits/deliverer.rs b/crates/kitsune-core/src/traits/deliverer.rs index c3e298ff2..72120d58d 100644 --- a/crates/kitsune-core/src/traits/deliverer.rs +++ b/crates/kitsune-core/src/traits/deliverer.rs @@ -1,5 +1,5 @@ -use crate::error::BoxError; use async_trait::async_trait; +use eyre::Result; use kitsune_db::model::{account::Account, favourite::Favourite, follower::Follow, post::Post}; use serde::{Deserialize, Serialize}; use std::sync::Arc; @@ -22,12 +22,12 @@ pub enum Action { #[async_trait] pub trait Deliverer: Send + Sync + 'static { - async fn deliver(&self, action: Action) -> Result<(), BoxError>; + async fn deliver(&self, action: Action) -> Result<()>; } #[async_trait] impl Deliverer for Arc { - async fn deliver(&self, action: Action) -> Result<(), BoxError> { + async fn deliver(&self, action: Action) -> Result<()> { (**self).deliver(action).await } } @@ -37,7 +37,7 @@ impl Deliverer for Vec where T: Deliverer, { - async fn deliver(&self, action: Action) -> Result<(), BoxError> { + async fn deliver(&self, action: Action) -> Result<()> { for deliverer in self { deliverer.deliver(action.clone()).await?; } diff --git a/crates/kitsune-core/src/traits/fetcher.rs b/crates/kitsune-core/src/traits/fetcher.rs index 6b6262810..1849dd91f 100644 --- a/crates/kitsune-core/src/traits/fetcher.rs +++ b/crates/kitsune-core/src/traits/fetcher.rs @@ -1,6 +1,6 @@ use super::Resolver; -use crate::error::BoxError; use async_trait::async_trait; +use eyre::Result; use kitsune_db::model::{account::Account, custom_emoji::CustomEmoji, post::Post}; use std::sync::Arc; use typed_builder::TypedBuilder; @@ -50,14 +50,11 @@ impl<'a> From<&'a str> for PostFetchOptions<'a> { pub trait Fetcher: Send + Sync + 'static { fn resolver(&self) -> Arc; - async fn fetch_account( - &self, - opts: AccountFetchOptions<'_>, - ) -> Result, BoxError>; + async fn fetch_account(&self, opts: AccountFetchOptions<'_>) -> Result>; - async fn fetch_emoji(&self, url: &str) -> Result, BoxError>; + async fn fetch_emoji(&self, url: &str) -> Result>; - async fn fetch_post(&self, opts: PostFetchOptions<'_>) -> Result, BoxError>; + async fn fetch_post(&self, opts: PostFetchOptions<'_>) -> Result>; } #[async_trait] @@ -66,18 +63,15 @@ impl Fetcher for Arc { (**self).resolver() } - async fn fetch_account( - &self, - opts: AccountFetchOptions<'_>, - ) -> Result, BoxError> { + async fn fetch_account(&self, opts: AccountFetchOptions<'_>) -> Result> { (**self).fetch_account(opts).await } - async fn fetch_emoji(&self, url: &str) -> Result, BoxError> { + async fn fetch_emoji(&self, url: &str) -> Result> { (**self).fetch_emoji(url).await } - async fn fetch_post(&self, opts: PostFetchOptions<'_>) -> Result, BoxError> { + async fn fetch_post(&self, opts: PostFetchOptions<'_>) -> Result> { (**self).fetch_post(opts).await } } @@ -91,10 +85,7 @@ where Arc::new(self.iter().map(Fetcher::resolver).collect::>()) } - async fn fetch_account( - &self, - opts: AccountFetchOptions<'_>, - ) -> Result, BoxError> { + async fn fetch_account(&self, opts: AccountFetchOptions<'_>) -> Result> { for fetcher in self { if let Some(account) = fetcher.fetch_account(opts).await? { return Ok(Some(account)); @@ -104,7 +95,7 @@ where Ok(None) } - async fn fetch_emoji(&self, url: &str) -> Result, BoxError> { + async fn fetch_emoji(&self, url: &str) -> Result> { for fetcher in self { if let Some(emoji) = fetcher.fetch_emoji(url).await? { return Ok(Some(emoji)); @@ -114,7 +105,7 @@ where Ok(None) } - async fn fetch_post(&self, opts: PostFetchOptions<'_>) -> Result, BoxError> { + async fn fetch_post(&self, opts: PostFetchOptions<'_>) -> Result> { for fetcher in self { if let Some(post) = fetcher.fetch_post(opts).await? { return Ok(Some(post)); diff --git a/crates/kitsune-core/src/traits/resolver.rs b/crates/kitsune-core/src/traits/resolver.rs index a2aa23566..6458d7efd 100644 --- a/crates/kitsune-core/src/traits/resolver.rs +++ b/crates/kitsune-core/src/traits/resolver.rs @@ -1,5 +1,5 @@ -use crate::error::BoxError; use async_trait::async_trait; +use eyre::Result; use serde::{Deserialize, Serialize}; use std::sync::Arc; @@ -20,7 +20,7 @@ pub trait Resolver: Send + Sync + 'static { &self, username: &str, domain: &str, - ) -> Result, BoxError>; + ) -> Result>; } #[async_trait] @@ -29,7 +29,7 @@ impl Resolver for Arc { &self, username: &str, domain: &str, - ) -> Result, BoxError> { + ) -> Result> { (**self).resolve_account(username, domain).await } } @@ -43,7 +43,7 @@ where &self, username: &str, domain: &str, - ) -> Result, BoxError> { + ) -> Result> { for resolver in self { if let Some(resource) = resolver.resolve_account(username, domain).await? { return Ok(Some(resource)); diff --git a/crates/kitsune-db/Cargo.toml b/crates/kitsune-db/Cargo.toml index cf4c226a1..ba7fe5965 100644 --- a/crates/kitsune-db/Cargo.toml +++ b/crates/kitsune-db/Cargo.toml @@ -24,7 +24,6 @@ iso8601-timestamp = { version = "0.2.17", features = ["diesel-pg"] } kitsune-config = { path = "../kitsune-config" } kitsune-language = { path = "../kitsune-language" } kitsune-type = { path = "../kitsune-type" } -miette = "7.2.0" num-derive = "0.4.2" num-traits = "0.2.18" rustls = "0.23.4" diff --git a/crates/kitsune-db/src/error.rs b/crates/kitsune-db/src/error.rs index e57e9002b..12daf1669 100644 --- a/crates/kitsune-db/src/error.rs +++ b/crates/kitsune-db/src/error.rs @@ -1,6 +1,5 @@ use core::fmt; use diesel_async::pooled_connection::bb8; -use miette::Diagnostic; use std::error::Error as StdError; use thiserror::Error; @@ -37,7 +36,7 @@ impl fmt::Display for IsoCodeConversionError { impl StdError for IsoCodeConversionError {} -#[derive(Debug, Diagnostic, Error)] +#[derive(Debug, Error)] pub enum Error { #[error(transparent)] Blocking(#[from] blowocking::Error), diff --git a/crates/kitsune-db/src/lib.rs b/crates/kitsune-db/src/lib.rs index d89c75a5d..584129a60 100644 --- a/crates/kitsune-db/src/lib.rs +++ b/crates/kitsune-db/src/lib.rs @@ -11,10 +11,9 @@ use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; use kitsune_config::database::Configuration as DatabaseConfig; use tracing_log::LogTracer; -pub use crate::{ - error::{Error, Result}, - pool::{PgPool, PoolError}, -}; +pub type PgPool = Pool; + +pub use crate::error::{Error, Result}; mod error; mod pool; @@ -75,5 +74,5 @@ pub async fn connect(config: &DatabaseConfig) -> Result { .await?; } - Ok(pool.into()) + Ok(pool) } diff --git a/crates/kitsune-db/src/pool.rs b/crates/kitsune-db/src/pool.rs index 8c9fa44c5..74af2d8d0 100644 --- a/crates/kitsune-db/src/pool.rs +++ b/crates/kitsune-db/src/pool.rs @@ -1,70 +1,27 @@ -use diesel_async::{ - pooled_connection::bb8::{self, Pool}, - scoped_futures::{ScopedFutureExt, ScopedFutureWrapper}, - AsyncConnection, AsyncPgConnection, -}; -use miette::Diagnostic; -use std::{ - fmt::{Debug, Display}, - future::Future, -}; -use thiserror::Error; - -#[derive(Debug, Diagnostic, Error)] -pub enum PoolError -where - E: Display + Debug, -{ - #[error(transparent)] - Pool(#[from] bb8::RunError), - - #[error("{0}")] - User(E), +#[macro_export] +macro_rules! with_connection { + ($pool:expr, |$conn_name:ident| $code:block) => {{ + let mut conn = $pool.get().await?; + let $conn_name = &mut *conn; + async move { $code }.await + }}; } -/// Small wrapper around [`Pool`] -/// -/// The intent of this API is to encourage and make short-lived ownership of connections easier. -/// With the traditional RAII guard based approach, it is rather hard (and/or ugly) to define clear scopes for connections -/// (especially when they are used *a lot* throughout the code). -/// -/// The API of this wrapper is based on closures, meaning you have no choice but to be aware of the scope. -/// And the extra level of indentation this forces is supposed to coerce users to keep the scope as small as possible. -#[derive(Clone)] -pub struct PgPool { - inner: Pool, -} - -impl PgPool { - /// Run the code inside a context with a database connection - pub async fn with_connection<'a, F, Fut, T, E>(&self, func: F) -> Result> - where - for<'conn> F: FnOnce(&'conn mut AsyncPgConnection) -> ScopedFutureWrapper<'conn, 'a, Fut>, - Fut: Future>, - E: Display + Debug, - { - let mut conn = self.inner.get().await?; - func(&mut conn).await.map_err(PoolError::User) - } - - /// Run the code inside a context with a database transaction - pub async fn with_transaction<'a, F, Fut, T, E>(&self, func: F) -> Result> - where - for<'conn> F: - FnOnce(&'conn mut AsyncPgConnection) -> ScopedFutureWrapper<'conn, 'a, Fut> + Send, - Fut: Future> + Send, - T: Send, - E: From + Debug + Display + Send, - { - let mut conn = self.inner.get().await?; - conn.transaction(|conn| func(conn).scope_boxed()) - .await - .map_err(PoolError::User) - } +#[macro_export] +macro_rules! with_connection_panicky { + ($pool:expr, $($other:tt)*) => {{ + let result: ::std::result::Result<_, Box> = async move { + let _ = $crate::with_connection!($pool, $($other)*); + Ok(()) + }.await; + result.unwrap(); + }}; } -impl From> for PgPool { - fn from(value: Pool) -> Self { - Self { inner: value } - } +#[macro_export] +macro_rules! with_transaction { + ($pool:expr, $func:expr) => {{ + let mut conn = $pool.get().await?; + conn.transaction(|conn| Box::pin(($func)(conn))).await + }}; } diff --git a/crates/kitsune-db/tests/unicode_collation.rs b/crates/kitsune-db/tests/unicode_collation.rs index cf7ef860b..026992cc1 100644 --- a/crates/kitsune-db/tests/unicode_collation.rs +++ b/crates/kitsune-db/tests/unicode_collation.rs @@ -1,11 +1,12 @@ use diesel::SelectableHelper; -use diesel_async::{scoped_futures::ScopedFutureExt, AsyncPgConnection, RunQueryDsl}; +use diesel_async::{AsyncPgConnection, RunQueryDsl}; use kitsune_db::{ model::{ account::{Account, ActorType, NewAccount}, user::{NewUser, User}, }, schema::{accounts, users}, + with_connection_panicky, }; use kitsune_test::database_test; use speedy_uuid::Uuid; @@ -65,30 +66,22 @@ async fn create_user(conn: &mut AsyncPgConnection, username: &str) -> Result; pub type Result = std::result::Result; -#[derive(Debug, Diagnostic, Error)] +#[derive(Debug, Error)] pub enum Error { #[error(transparent)] Address(#[from] lettre::address::AddressError), @@ -35,15 +31,3 @@ pub enum Error { #[error(transparent)] Rendering(#[from] mrml::prelude::render::Error), } - -impl From> for Error -where - E: Into + Debug + Display, -{ - fn from(value: kitsune_db::PoolError) -> Self { - match value { - kitsune_db::PoolError::Pool(err) => err.into(), - kitsune_db::PoolError::User(err) => err.into(), - } - } -} diff --git a/crates/kitsune-email/src/service.rs b/crates/kitsune-email/src/service.rs index 9e4c84986..fc844c735 100644 --- a/crates/kitsune-email/src/service.rs +++ b/crates/kitsune-email/src/service.rs @@ -1,10 +1,9 @@ use crate::{error::Result, mails::confirm_account::ConfirmAccount, MailSender}; use diesel::{ExpressionMethods, NullableExpressionMethods, QueryDsl}; use diesel_async::RunQueryDsl; -use kitsune_db::{function::now, model::user::User, schema::users, PgPool}; +use kitsune_db::{function::now, model::user::User, schema::users, with_connection, PgPool}; use kitsune_url::UrlService; use lettre::{AsyncSmtpTransport, Tokio1Executor}; -use scoped_futures::ScopedFutureExt; use speedy_uuid::Uuid; use typed_builder::TypedBuilder; @@ -27,31 +26,27 @@ impl Mailing { } pub async fn mark_as_confirmed(&self, user_id: Uuid) -> Result<()> { - self.db_pool - .with_connection(|db_conn| { - diesel::update(users::table.find(user_id)) - .set(users::confirmed_at.eq(now().nullable())) - .execute(db_conn) - .scoped() - }) - .await?; + with_connection!(self.db_pool, |db_conn| { + diesel::update(users::table.find(user_id)) + .set(users::confirmed_at.eq(now().nullable())) + .execute(db_conn) + .await + })?; Ok(()) } pub async fn mark_as_confirmed_by_token(&self, confirmation_token: &str) -> Result<()> { - self.db_pool - .with_connection(|db_conn| { - diesel::update( - users::table - .filter(users::confirmation_token.eq(confirmation_token)) - .filter(users::confirmed_at.is_null()), - ) - .set(users::confirmed_at.eq(now().nullable())) - .execute(db_conn) - .scoped() - }) - .await?; + with_connection!(self.db_pool, |db_conn| { + diesel::update( + users::table + .filter(users::confirmation_token.eq(confirmation_token)) + .filter(users::confirmed_at.is_null()), + ) + .set(users::confirmed_at.eq(now().nullable())) + .execute(db_conn) + .await + })?; Ok(()) } diff --git a/crates/kitsune-embed/src/lib.rs b/crates/kitsune-embed/src/lib.rs index cd8b0f614..806a13d1d 100644 --- a/crates/kitsune-embed/src/lib.rs +++ b/crates/kitsune-embed/src/lib.rs @@ -1,5 +1,5 @@ use diesel::{OptionalExtension, QueryDsl}; -use diesel_async::{pooled_connection::bb8, scoped_futures::ScopedFutureExt, RunQueryDsl}; +use diesel_async::{pooled_connection::bb8, RunQueryDsl}; use embed_sdk::EmbedWithExpire; use http::{Method, Request}; use iso8601_timestamp::Timestamp; @@ -7,13 +7,13 @@ use kitsune_db::{ json::Json, model::link_preview::{ConflictLinkPreviewChangeset, LinkPreview, NewLinkPreview}, schema::link_previews, - PgPool, + with_connection, PgPool, }; 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 std::fmt::Debug; use typed_builder::TypedBuilder; pub use embed_sdk; @@ -46,18 +46,6 @@ pub enum Error { Pool(#[from] bb8::RunError), } -impl From> for Error -where - E: Into + Debug + Display, -{ - fn from(value: kitsune_db::PoolError) -> Self { - match value { - kitsune_db::PoolError::Pool(err) => err.into(), - kitsune_db::PoolError::User(err) => err.into(), - } - } -} - #[derive(Clone, TypedBuilder)] pub struct Client { db_pool: PgPool, @@ -83,19 +71,13 @@ impl Client { } pub async fn fetch_embed(&self, url: &str) -> Result> { - let embed_data = self - .db_pool - .with_connection(|db_conn| { - async move { - link_previews::table - .find(url) - .get_result::>(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; + let embed_data = with_connection!(self.db_pool, |db_conn| { + link_previews::table + .find(url) + .get_result::>(db_conn) + .await + .optional() + })?; if let Some(data) = embed_data { if data.expires_at > Timestamp::now_utc() { @@ -112,25 +94,22 @@ impl Client { let response = HttpClient::execute(&self.http_client, request).await?; let (expires_at, embed_data): EmbedWithExpire = response.json().await?; - let embed_data = self - .db_pool - .with_connection(|db_conn| { - diesel::insert_into(link_previews::table) - .values(NewLinkPreview { - url, - embed_data: Json(&embed_data), - expires_at, - }) - .on_conflict(link_previews::url) - .do_update() - .set(ConflictLinkPreviewChangeset { - embed_data: Json(&embed_data), - expires_at, - }) - .get_result(db_conn) - .scoped() - }) - .await?; + let embed_data = with_connection!(self.db_pool, |db_conn| { + diesel::insert_into(link_previews::table) + .values(NewLinkPreview { + url, + embed_data: Json(&embed_data), + expires_at, + }) + .on_conflict(link_previews::url) + .do_update() + .set(ConflictLinkPreviewChangeset { + embed_data: Json(&embed_data), + expires_at, + }) + .get_result(db_conn) + .await + })?; Ok(embed_data) } diff --git a/crates/kitsune-federation-filter/Cargo.toml b/crates/kitsune-federation-filter/Cargo.toml index 397207e8d..069ac0102 100644 --- a/crates/kitsune-federation-filter/Cargo.toml +++ b/crates/kitsune-federation-filter/Cargo.toml @@ -9,7 +9,6 @@ license.workspace = true globset = "0.4.14" kitsune-config = { path = "../kitsune-config" } kitsune-type = { path = "../kitsune-type" } -miette = "7.2.0" thiserror = "1.0.58" url = "2.5.0" diff --git a/crates/kitsune-federation-filter/src/error.rs b/crates/kitsune-federation-filter/src/error.rs index 09dc106d6..99d0991e5 100644 --- a/crates/kitsune-federation-filter/src/error.rs +++ b/crates/kitsune-federation-filter/src/error.rs @@ -1,9 +1,8 @@ -use miette::Diagnostic; use thiserror::Error; pub type Result = std::result::Result; -#[derive(Debug, Diagnostic, Error)] +#[derive(Debug, 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 2765720bc..497f10327 100644 --- a/crates/kitsune-jobs/Cargo.toml +++ b/crates/kitsune-jobs/Cargo.toml @@ -10,11 +10,11 @@ athena = { path = "../../lib/athena" } derive_more = { version = "1.0.0-beta.6", features = ["from"] } diesel = "2.1.5" diesel-async = "0.4.1" +eyre = "0.6.12" futures-util = "0.3.30" kitsune-core = { path = "../kitsune-core" } kitsune-db = { path = "../kitsune-db" } kitsune-email = { path = "../kitsune-email" } -miette = "7.2.0" scoped-futures = "0.1.3" serde = { version = "1.0.197", features = ["derive"] } speedy-uuid = { path = "../../lib/speedy-uuid" } diff --git a/crates/kitsune-jobs/src/deliver/accept.rs b/crates/kitsune-jobs/src/deliver/accept.rs index ae53696b9..b4f0863ca 100644 --- a/crates/kitsune-jobs/src/deliver/accept.rs +++ b/crates/kitsune-jobs/src/deliver/accept.rs @@ -2,8 +2,7 @@ use crate::{JobRunnerContext, Runnable}; use diesel::{OptionalExtension, QueryDsl}; use diesel_async::RunQueryDsl; use kitsune_core::traits::deliverer::Action; -use kitsune_db::{model::follower::Follow, schema::accounts_follows}; -use scoped_futures::ScopedFutureExt; +use kitsune_db::{model::follower::Follow, schema::accounts_follows, with_connection}; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; @@ -14,32 +13,23 @@ pub struct DeliverAccept { impl Runnable for DeliverAccept { type Context = JobRunnerContext; - type Error = miette::Report; + type Error = eyre::Report; #[instrument(skip_all, fields(follow_id = %self.follow_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { - let follow = ctx - .db_pool - .with_connection(|db_conn| { - async move { - accounts_follows::table - .find(self.follow_id) - .get_result::(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; + let follow = with_connection!(ctx.db_pool, |db_conn| { + accounts_follows::table + .find(self.follow_id) + .get_result::(db_conn) + .await + .optional() + })?; let Some(follow) = follow else { return Ok(()); }; - ctx.deliverer - .deliver(Action::AcceptFollow(follow)) - .await - .map_err(|err| miette::Report::new_boxed(err.into()))?; + ctx.deliverer.deliver(Action::AcceptFollow(follow)).await?; Ok(()) } diff --git a/crates/kitsune-jobs/src/deliver/create.rs b/crates/kitsune-jobs/src/deliver/create.rs index 3d157c1a2..24eb7bd0c 100644 --- a/crates/kitsune-jobs/src/deliver/create.rs +++ b/crates/kitsune-jobs/src/deliver/create.rs @@ -3,8 +3,7 @@ use athena::Runnable; use diesel::{OptionalExtension, QueryDsl, SelectableHelper}; use diesel_async::RunQueryDsl; use kitsune_core::traits::deliverer::Action; -use kitsune_db::{model::post::Post, schema::posts}; -use scoped_futures::ScopedFutureExt; +use kitsune_db::{model::post::Post, schema::posts, with_connection}; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; @@ -15,33 +14,24 @@ pub struct DeliverCreate { impl Runnable for DeliverCreate { type Context = JobRunnerContext; - type Error = miette::Report; + type Error = eyre::Report; #[instrument(skip_all, fields(post_id = %self.post_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { - let post = ctx - .db_pool - .with_connection(|db_conn| { - async move { - posts::table - .find(self.post_id) - .select(Post::as_select()) - .get_result::(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; + let post = with_connection!(ctx.db_pool, |db_conn| { + posts::table + .find(self.post_id) + .select(Post::as_select()) + .get_result::(db_conn) + .await + .optional() + })?; let Some(post) = post else { return Ok(()); }; - ctx.deliverer - .deliver(Action::Create(post)) - .await - .map_err(|err| miette::Report::new_boxed(err.into()))?; + ctx.deliverer.deliver(Action::Create(post)).await?; Ok(()) } diff --git a/crates/kitsune-jobs/src/deliver/delete.rs b/crates/kitsune-jobs/src/deliver/delete.rs index 3295c8c5d..7c7a2131c 100644 --- a/crates/kitsune-jobs/src/deliver/delete.rs +++ b/crates/kitsune-jobs/src/deliver/delete.rs @@ -3,8 +3,7 @@ use athena::Runnable; use diesel::{OptionalExtension, QueryDsl, SelectableHelper}; use diesel_async::RunQueryDsl; use kitsune_core::traits::deliverer::Action; -use kitsune_db::{model::post::Post, schema::posts}; -use scoped_futures::ScopedFutureExt; +use kitsune_db::{model::post::Post, schema::posts, with_connection}; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; @@ -15,41 +14,30 @@ pub struct DeliverDelete { impl Runnable for DeliverDelete { type Context = JobRunnerContext; - type Error = miette::Report; + type Error = eyre::Report; #[instrument(skip_all, fields(post_id = %self.post_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { - let post = ctx - .db_pool - .with_connection(|db_conn| { - async move { - posts::table - .find(self.post_id) - .select(Post::as_select()) - .get_result::(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; + let post = with_connection!(ctx.db_pool, |db_conn| { + posts::table + .find(self.post_id) + .select(Post::as_select()) + .get_result::(db_conn) + .await + .optional() + })?; let Some(post) = post else { return Ok(()); }; - ctx.deliverer - .deliver(Action::Delete(post)) - .await - .map_err(|err| miette::Report::new_boxed(err.into()))?; + ctx.deliverer.deliver(Action::Delete(post)).await?; - ctx.db_pool - .with_connection(|db_conn| { - diesel::delete(posts::table.find(self.post_id)) - .execute(db_conn) - .scoped() - }) - .await?; + with_connection!(ctx.db_pool, |db_conn| { + diesel::delete(posts::table.find(self.post_id)) + .execute(db_conn) + .await + })?; Ok(()) } diff --git a/crates/kitsune-jobs/src/deliver/favourite.rs b/crates/kitsune-jobs/src/deliver/favourite.rs index 1dbc8d152..46a7b2d96 100644 --- a/crates/kitsune-jobs/src/deliver/favourite.rs +++ b/crates/kitsune-jobs/src/deliver/favourite.rs @@ -3,8 +3,7 @@ use athena::Runnable; use diesel::QueryDsl; use diesel_async::RunQueryDsl; use kitsune_core::traits::deliverer::Action; -use kitsune_db::{model::favourite::Favourite, schema::posts_favourites}; -use scoped_futures::ScopedFutureExt; +use kitsune_db::{model::favourite::Favourite, schema::posts_favourites, with_connection}; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; @@ -15,24 +14,18 @@ pub struct DeliverFavourite { impl Runnable for DeliverFavourite { type Context = JobRunnerContext; - type Error = miette::Report; + type Error = eyre::Report; #[instrument(skip_all, fields(favourite_id = %self.favourite_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { - let favourite = ctx - .db_pool - .with_connection(|db_conn| { - posts_favourites::table - .find(self.favourite_id) - .get_result::(db_conn) - .scoped() - }) - .await?; + let favourite = with_connection!(ctx.db_pool, |db_conn| { + posts_favourites::table + .find(self.favourite_id) + .get_result::(db_conn) + .await + })?; - ctx.deliverer - .deliver(Action::Favourite(favourite)) - .await - .map_err(|err| miette::Report::new_boxed(err.into()))?; + ctx.deliverer.deliver(Action::Favourite(favourite)).await?; Ok(()) } diff --git a/crates/kitsune-jobs/src/deliver/follow.rs b/crates/kitsune-jobs/src/deliver/follow.rs index b7e5312ce..1465999a6 100644 --- a/crates/kitsune-jobs/src/deliver/follow.rs +++ b/crates/kitsune-jobs/src/deliver/follow.rs @@ -3,8 +3,7 @@ use athena::Runnable; use diesel::{OptionalExtension, QueryDsl}; use diesel_async::RunQueryDsl; use kitsune_core::traits::deliverer::Action; -use kitsune_db::{model::follower::Follow, schema::accounts_follows}; -use scoped_futures::ScopedFutureExt; +use kitsune_db::{model::follower::Follow, schema::accounts_follows, with_connection}; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; @@ -15,32 +14,23 @@ pub struct DeliverFollow { impl Runnable for DeliverFollow { type Context = JobRunnerContext; - type Error = miette::Report; + type Error = eyre::Report; #[instrument(skip_all, fields(follow_id = %self.follow_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { - let follow = ctx - .db_pool - .with_connection(|db_conn| { - async move { - accounts_follows::table - .find(self.follow_id) - .get_result::(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; + let follow = with_connection!(ctx.db_pool, |db_conn| { + accounts_follows::table + .find(self.follow_id) + .get_result::(db_conn) + .await + .optional() + })?; let Some(follow) = follow else { return Ok(()); }; - ctx.deliverer - .deliver(Action::Follow(follow)) - .await - .map_err(|err| miette::Report::new_boxed(err.into()))?; + ctx.deliverer.deliver(Action::Follow(follow)).await?; Ok(()) } diff --git a/crates/kitsune-jobs/src/deliver/reject.rs b/crates/kitsune-jobs/src/deliver/reject.rs index 0d0fb50b9..050431acf 100644 --- a/crates/kitsune-jobs/src/deliver/reject.rs +++ b/crates/kitsune-jobs/src/deliver/reject.rs @@ -2,8 +2,7 @@ use crate::{JobRunnerContext, Runnable}; use diesel::{OptionalExtension, QueryDsl}; use diesel_async::RunQueryDsl; use kitsune_core::traits::deliverer::Action; -use kitsune_db::{model::follower::Follow, schema::accounts_follows}; -use scoped_futures::ScopedFutureExt; +use kitsune_db::{model::follower::Follow, schema::accounts_follows, with_connection}; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; @@ -14,40 +13,29 @@ pub struct DeliverReject { impl Runnable for DeliverReject { type Context = JobRunnerContext; - type Error = miette::Report; + type Error = eyre::Report; #[instrument(skip_all, fields(follow_id = %self.follow_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { - let follow = ctx - .db_pool - .with_connection(|db_conn| { - async move { - accounts_follows::table - .find(self.follow_id) - .get_result::(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; + let follow = with_connection!(ctx.db_pool, |db_conn| { + accounts_follows::table + .find(self.follow_id) + .get_result::(db_conn) + .await + .optional() + })?; let Some(follow) = follow else { return Ok(()); }; - ctx.deliverer - .deliver(Action::RejectFollow(follow)) - .await - .map_err(|err| miette::Report::new_boxed(err.into()))?; + ctx.deliverer.deliver(Action::RejectFollow(follow)).await?; - ctx.db_pool - .with_connection(|db_conn| { - diesel::delete(accounts_follows::table.find(self.follow_id)) - .execute(db_conn) - .scoped() - }) - .await?; + with_connection!(ctx.db_pool, |db_conn| { + diesel::delete(accounts_follows::table.find(self.follow_id)) + .execute(db_conn) + .await + })?; Ok(()) } diff --git a/crates/kitsune-jobs/src/deliver/unfavourite.rs b/crates/kitsune-jobs/src/deliver/unfavourite.rs index 1cd9133ce..046c000de 100644 --- a/crates/kitsune-jobs/src/deliver/unfavourite.rs +++ b/crates/kitsune-jobs/src/deliver/unfavourite.rs @@ -3,8 +3,7 @@ use athena::Runnable; use diesel::{OptionalExtension, QueryDsl}; use diesel_async::RunQueryDsl; use kitsune_core::traits::deliverer::Action; -use kitsune_db::{model::favourite::Favourite, schema::posts_favourites}; -use scoped_futures::ScopedFutureExt; +use kitsune_db::{model::favourite::Favourite, schema::posts_favourites, with_connection}; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; @@ -15,23 +14,17 @@ pub struct DeliverUnfavourite { impl Runnable for DeliverUnfavourite { type Context = JobRunnerContext; - type Error = miette::Report; + type Error = eyre::Report; #[instrument(skip_all, fields(favourite_id = %self.favourite_id))] async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { - let favourite = ctx - .db_pool - .with_connection(|db_conn| { - async move { - posts_favourites::table - .find(self.favourite_id) - .get_result::(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; + let favourite = with_connection!(ctx.db_pool, |db_conn| { + posts_favourites::table + .find(self.favourite_id) + .get_result::(db_conn) + .await + .optional() + })?; let Some(favourite) = favourite else { return Ok(()); @@ -39,17 +32,14 @@ impl Runnable for DeliverUnfavourite { ctx.deliverer .deliver(Action::Unfavourite(favourite)) - .await - .map_err(|err| miette::Report::new_boxed(err.into()))?; - - ctx.db_pool - .with_connection(|db_conn| { - diesel::delete(posts_favourites::table.find(self.favourite_id)) - .execute(db_conn) - .scoped() - }) .await?; + with_connection!(ctx.db_pool, |db_conn| { + diesel::delete(posts_favourites::table.find(self.favourite_id)) + .execute(db_conn) + .await + })?; + Ok(()) } } diff --git a/crates/kitsune-jobs/src/deliver/unfollow.rs b/crates/kitsune-jobs/src/deliver/unfollow.rs index 26abbea60..cfa1db94a 100644 --- a/crates/kitsune-jobs/src/deliver/unfollow.rs +++ b/crates/kitsune-jobs/src/deliver/unfollow.rs @@ -3,8 +3,7 @@ use athena::Runnable; use diesel::{OptionalExtension, QueryDsl}; use diesel_async::RunQueryDsl; use kitsune_core::traits::deliverer::Action; -use kitsune_db::{model::follower::Follow, schema::accounts_follows}; -use scoped_futures::ScopedFutureExt; +use kitsune_db::{model::follower::Follow, schema::accounts_follows, with_connection}; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; @@ -15,39 +14,28 @@ pub struct DeliverUnfollow { impl Runnable for DeliverUnfollow { type Context = JobRunnerContext; - type Error = miette::Report; + type Error = eyre::Report; async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { - let follow = ctx - .db_pool - .with_connection(|db_conn| { - async move { - accounts_follows::table - .find(self.follow_id) - .get_result::(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; + let follow = with_connection!(ctx.db_pool, |db_conn| { + accounts_follows::table + .find(self.follow_id) + .get_result::(db_conn) + .await + .optional() + })?; let Some(follow) = follow else { return Ok(()); }; - ctx.deliverer - .deliver(Action::Unfollow(follow)) - .await - .map_err(|err| miette::Report::new_boxed(err.into()))?; + ctx.deliverer.deliver(Action::Unfollow(follow)).await?; - ctx.db_pool - .with_connection(|db_conn| { - diesel::delete(accounts_follows::table.find(self.follow_id)) - .execute(db_conn) - .scoped() - }) - .await?; + with_connection!(ctx.db_pool, |db_conn| { + diesel::delete(accounts_follows::table.find(self.follow_id)) + .execute(db_conn) + .await + })?; Ok(()) } diff --git a/crates/kitsune-jobs/src/deliver/update.rs b/crates/kitsune-jobs/src/deliver/update.rs index b6dddca7f..ae605b86b 100644 --- a/crates/kitsune-jobs/src/deliver/update.rs +++ b/crates/kitsune-jobs/src/deliver/update.rs @@ -6,8 +6,8 @@ use kitsune_core::traits::deliverer::Action; use kitsune_db::{ model::{account::Account, post::Post}, schema::{accounts, posts}, + with_connection, }; -use scoped_futures::ScopedFutureExt; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; @@ -25,25 +25,19 @@ pub struct DeliverUpdate { impl Runnable for DeliverUpdate { type Context = JobRunnerContext; - type Error = miette::Report; + type Error = eyre::Report; async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { let action = match self.entity { UpdateEntity::Account => { - let account = ctx - .db_pool - .with_connection(|db_conn| { - async move { - accounts::table - .find(self.id) - .select(Account::as_select()) - .get_result(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; + let account = with_connection!(ctx.db_pool, |db_conn| { + accounts::table + .find(self.id) + .select(Account::as_select()) + .get_result(db_conn) + .await + .optional() + })?; let Some(account) = account else { return Ok(()); @@ -52,20 +46,14 @@ impl Runnable for DeliverUpdate { Action::UpdateAccount(account) } UpdateEntity::Status => { - let post = ctx - .db_pool - .with_connection(|db_conn| { - async move { - posts::table - .find(self.id) - .select(Post::as_select()) - .get_result(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; + let post = with_connection!(ctx.db_pool, |db_conn| { + posts::table + .find(self.id) + .select(Post::as_select()) + .get_result(db_conn) + .await + .optional() + })?; let Some(post) = post else { return Ok(()); @@ -75,10 +63,7 @@ impl Runnable for DeliverUpdate { } }; - ctx.deliverer - .deliver(action) - .await - .map_err(|err| miette::Report::new_boxed(err.into()))?; + ctx.deliverer.deliver(action).await?; Ok(()) } diff --git a/crates/kitsune-jobs/src/lib.rs b/crates/kitsune-jobs/src/lib.rs index f9686e304..315fe863e 100644 --- a/crates/kitsune-jobs/src/lib.rs +++ b/crates/kitsune-jobs/src/lib.rs @@ -19,11 +19,9 @@ use kitsune_db::{ json::Json, model::job_context::{JobContext, NewJobContext}, schema::job_context, - PgPool, + with_connection, PgPool, }; use kitsune_email::MailingService; -use miette::IntoDiagnostic; -use scoped_futures::ScopedFutureExt; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; use typed_builder::TypedBuilder; @@ -57,7 +55,7 @@ pub enum Job { impl Runnable for Job { type Context = JobRunnerContext; - type Error = miette::Report; + type Error = eyre::Report; async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { match self { @@ -89,37 +87,32 @@ impl KitsuneContextRepo { impl JobContextRepository for KitsuneContextRepo { type JobContext = Job; - type Error = miette::Report; + type Error = eyre::Report; type Stream = BoxStream<'static, Result<(Uuid, Self::JobContext), Self::Error>>; async fn fetch_context(&self, job_ids: I) -> Result where I: Iterator + Send + 'static, { - let stream = self - .db_pool - .with_connection(|conn| { - job_context::table - .filter(job_context::id.eq_any(job_ids)) - .load_stream::>(conn) - .scoped() - }) - .await?; + let stream = with_connection!(self.db_pool, |conn| { + job_context::table + .filter(job_context::id.eq_any(job_ids)) + .load_stream::>(conn) + .await + })?; Ok(stream .map_ok(|ctx| (ctx.id, ctx.context.0)) - .map(IntoDiagnostic::into_diagnostic) + .map_err(eyre::Report::from) .boxed()) } async fn remove_context(&self, job_id: Uuid) -> Result<(), Self::Error> { - self.db_pool - .with_connection(|conn| { - diesel::delete(job_context::table.find(job_id)) - .execute(conn) - .scoped() - }) - .await?; + with_connection!(self.db_pool, |conn| { + diesel::delete(job_context::table.find(job_id)) + .execute(conn) + .await + })?; Ok(()) } @@ -129,17 +122,15 @@ impl JobContextRepository for KitsuneContextRepo { job_id: Uuid, context: Self::JobContext, ) -> Result<(), Self::Error> { - self.db_pool - .with_connection(|conn| { - diesel::insert_into(job_context::table) - .values(NewJobContext { - id: job_id, - context: Json(context), - }) - .execute(conn) - .scoped() - }) - .await?; + with_connection!(self.db_pool, |conn| { + diesel::insert_into(job_context::table) + .values(NewJobContext { + id: job_id, + context: Json(context), + }) + .execute(conn) + .await + })?; Ok(()) } diff --git a/crates/kitsune-jobs/src/mailing/confirmation.rs b/crates/kitsune-jobs/src/mailing/confirmation.rs index ad0b268a5..62de30776 100644 --- a/crates/kitsune-jobs/src/mailing/confirmation.rs +++ b/crates/kitsune-jobs/src/mailing/confirmation.rs @@ -2,8 +2,7 @@ use crate::JobRunnerContext; use athena::Runnable; use diesel::{QueryDsl, SelectableHelper}; use diesel_async::RunQueryDsl; -use kitsune_db::{model::user::User, schema::users}; -use scoped_futures::ScopedFutureExt; +use kitsune_db::{model::user::User, schema::users, with_connection}; use serde::{Deserialize, Serialize}; use speedy_uuid::Uuid; @@ -14,7 +13,7 @@ pub struct SendConfirmationMail { impl Runnable for SendConfirmationMail { type Context = JobRunnerContext; - type Error = miette::Report; + type Error = eyre::Report; async fn run(&self, ctx: &Self::Context) -> Result<(), Self::Error> { let mailing_service = &ctx.service.mailing; @@ -24,16 +23,13 @@ impl Runnable for SendConfirmationMail { mailing_service.mark_as_confirmed(self.user_id).await?; } - let user = ctx - .db_pool - .with_connection(|db_conn| { - users::table - .find(self.user_id) - .select(User::as_select()) - .get_result(db_conn) - .scoped() - }) - .await?; + let user = with_connection!(ctx.db_pool, |db_conn| { + users::table + .find(self.user_id) + .select(User::as_select()) + .get_result(db_conn) + .await + })?; mailing_service.send_confirmation_email(&user).await?; diff --git a/crates/kitsune-observability/Cargo.toml b/crates/kitsune-observability/Cargo.toml index 3e36d5926..d8905d3c2 100644 --- a/crates/kitsune-observability/Cargo.toml +++ b/crates/kitsune-observability/Cargo.toml @@ -7,6 +7,7 @@ license.workspace = true [dependencies] async-trait = "0.1.79" +eyre = "0.6.12" http-body-util = "0.1.1" http-compat = { path = "../../lib/http-compat" } hyper = { version = "1.2.0", default-features = false } @@ -16,7 +17,6 @@ metrics = "=0.22.0" metrics-opentelemetry = { git = "https://github.com/aumetra/metrics-opentelemetry.git", rev = "95537b16370e595981e195be52f98ea5983a7a8e" } metrics-tracing-context = "0.15.0" metrics-util = "0.16.3" -miette = "7.2.0" opentelemetry = { version = "0.22.0", default-features = false, features = [ "trace", ] } diff --git a/crates/kitsune-observability/src/lib.rs b/crates/kitsune-observability/src/lib.rs index e4b28d55d..7f9d827a7 100644 --- a/crates/kitsune-observability/src/lib.rs +++ b/crates/kitsune-observability/src/lib.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use eyre::WrapErr; use http_body_util::BodyExt; use http_compat::Compat; 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}, @@ -67,18 +67,13 @@ macro_rules! build_exporter { }}; } -fn initialise_logging(tracer: T) -> miette::Result<()> +fn initialise_logging(tracer: T) -> eyre::Result<()> where T: Tracer + PreSampledTracer + Send + Sync + 'static, { let env_filter = env::var("RUST_LOG") - .into_diagnostic() - .and_then(|targets| { - targets - .parse() - .into_diagnostic() - .wrap_err("Failed to parse RUST_LOG value") - }) + .map_err(eyre::Report::from) + .and_then(|targets| targets.parse().wrap_err("Failed to parse RUST_LOG value")) .unwrap_or_else(|_| Targets::default().with_default(LevelFilter::INFO)); let subscriber = Registry::default() @@ -89,22 +84,20 @@ where let subscriber = subscriber.with(MetricsLayer::new()); tracing::subscriber::set_global_default(subscriber) - .into_diagnostic() .wrap_err("Couldn't install the global tracing subscriber")?; Ok(()) } -fn initialise_metrics(meter: Meter) -> miette::Result<()> { +fn initialise_metrics(meter: Meter) -> eyre::Result<()> { let recorder = TracingContextLayer::all().layer(OpenTelemetryRecorder::new(meter)); metrics::set_global_recorder(recorder) - .into_diagnostic() .wrap_err("Couldn't install the global metrics recorder")?; Ok(()) } -pub fn initialise(app_name: &'static str, config: &Configuration) -> miette::Result<()> { +pub fn initialise(app_name: &'static str, config: &Configuration) -> eyre::Result<()> { if let Some(ref opentelemetry_config) = config.opentelemetry { let http_client = HttpClientAdapter { inner: kitsune_http_client::Client::default(), @@ -120,8 +113,7 @@ pub fn initialise(app_name: &'static str, config: &Configuration) -> miette::Res let tracer = opentelemetry_otlp::new_pipeline() .tracing() .with_exporter(trace_exporter) - .install_batch(Tokio) - .into_diagnostic()?; + .install_batch(Tokio)?; initialise_logging(tracer)?; @@ -135,8 +127,7 @@ pub fn initialise(app_name: &'static str, config: &Configuration) -> miette::Res let meter_provider = opentelemetry_otlp::new_pipeline() .metrics(Tokio) .with_exporter(metrics_exporter) - .build() - .into_diagnostic()?; + .build()?; initialise_metrics(meter_provider.meter(app_name))?; } else { diff --git a/crates/kitsune-oidc/Cargo.toml b/crates/kitsune-oidc/Cargo.toml index b7dc19a0e..f3c6c1416 100644 --- a/crates/kitsune-oidc/Cargo.toml +++ b/crates/kitsune-oidc/Cargo.toml @@ -11,7 +11,6 @@ http = "1.1.0" http-compat = { path = "../../lib/http-compat" } kitsune-config = { path = "../kitsune-config" } kitsune-http-client = { path = "../kitsune-http-client" } -miette = "7.2.0" moka = { version = "0.12.5", features = ["future"] } multiplex-pool = { path = "../../lib/multiplex-pool" } once_cell = "1.19.0" diff --git a/crates/kitsune-oidc/src/error.rs b/crates/kitsune-oidc/src/error.rs index aac546055..de10ab221 100644 --- a/crates/kitsune-oidc/src/error.rs +++ b/crates/kitsune-oidc/src/error.rs @@ -1,4 +1,3 @@ -use miette::Diagnostic; use openidconnect::{ core::CoreErrorResponseType, ClaimsVerificationError, DiscoveryError, RequestTokenError, SigningError, StandardErrorResponse, @@ -7,7 +6,7 @@ use thiserror::Error; pub type Result = std::result::Result; -#[derive(Debug, Diagnostic, Error)] +#[derive(Debug, Error)] pub enum Error { #[error(transparent)] ClaimsVerification(#[from] ClaimsVerificationError), diff --git a/crates/kitsune-search/Cargo.toml b/crates/kitsune-search/Cargo.toml index e2df627ce..427b45a4f 100644 --- a/crates/kitsune-search/Cargo.toml +++ b/crates/kitsune-search/Cargo.toml @@ -17,7 +17,6 @@ futures-util = "0.3.30" kitsune-config = { path = "../kitsune-config" } kitsune-db = { path = "../kitsune-db" } kitsune-language = { path = "../kitsune-language" } -miette = "7.2.0" serde = { version = "1.0.197", features = ["derive"] } speedy-uuid = { path = "../../lib/speedy-uuid" } strum = { version = "0.26.2", features = ["derive"] } diff --git a/crates/kitsune-search/src/error.rs b/crates/kitsune-search/src/error.rs index 3e7f24866..dc94a6652 100644 --- a/crates/kitsune-search/src/error.rs +++ b/crates/kitsune-search/src/error.rs @@ -1,9 +1,8 @@ use diesel_async::pooled_connection::bb8; -use miette::Diagnostic; -use std::fmt::{Debug, Display}; +use std::fmt::Debug; use thiserror::Error; -#[derive(Debug, Diagnostic, Error)] +#[derive(Debug, Error)] pub enum Error { #[error(transparent)] Database(#[from] diesel::result::Error), @@ -15,15 +14,3 @@ pub enum Error { #[error(transparent)] Meilisearch(#[from] meilisearch_sdk::errors::Error), } - -impl From> for Error -where - E: Into + Debug + Display, -{ - fn from(value: kitsune_db::PoolError) -> Self { - match value { - kitsune_db::PoolError::Pool(err) => err.into(), - kitsune_db::PoolError::User(err) => err.into(), - } - } -} diff --git a/crates/kitsune-search/src/sql.rs b/crates/kitsune-search/src/sql.rs index a6048f50e..a2f76485a 100644 --- a/crates/kitsune-search/src/sql.rs +++ b/crates/kitsune-search/src/sql.rs @@ -1,6 +1,6 @@ use super::{Result, SearchBackend, SearchIndex, SearchItem, SearchResultReference}; use diesel::{ExpressionMethods, QueryDsl}; -use diesel_async::{scoped_futures::ScopedFutureExt, RunQueryDsl}; +use diesel_async::RunQueryDsl; use diesel_full_text_search::{websearch_to_tsquery_with_search_config, TsVectorExtensions}; use futures_util::TryStreamExt; use kitsune_config::language_detection::Configuration as LanguageDetectionConfig; @@ -9,7 +9,7 @@ use kitsune_db::{ lang::LanguageIsoCode, model::post::Visibility, schema::{accounts, posts}, - PgPool, + with_connection, PgPool, }; use speedy_uuid::Uuid; use typed_builder::TypedBuilder; @@ -62,23 +62,17 @@ impl SearchBackend for SearchService { query = query.filter(accounts::id.lt(max_id)); } - let results = self - .db_pool - .with_connection(move |db_conn| { - async move { - query - .limit(max_results as i64) - .offset(offset as i64) - .select(accounts::id) - .load_stream(db_conn) - .await? - .map_ok(|id| SearchResultReference { index, id }) - .try_collect() - .await - } - .scoped() - }) - .await?; + let results = with_connection!(self.db_pool, |db_conn| { + query + .limit(max_results as i64) + .offset(offset as i64) + .select(accounts::id) + .load_stream(db_conn) + .await? + .map_ok(|id| SearchResultReference { index, id }) + .try_collect() + .await + })?; Ok(results) } @@ -94,27 +88,20 @@ impl SearchBackend for SearchService { query = query.filter(posts::id.lt(max_id)); } - let results = self - .db_pool - .with_connection(|db_conn| { - async move { - query - .filter( - posts::visibility - .eq_any([Visibility::Public, Visibility::Unlisted]), - ) - .limit(max_results as i64) - .offset(offset as i64) - .select(posts::id) - .load_stream(db_conn) - .await? - .map_ok(|id| SearchResultReference { index, id }) - .try_collect() - .await - } - .scoped() - }) - .await?; + let results = with_connection!(self.db_pool, |db_conn| { + query + .filter( + posts::visibility.eq_any([Visibility::Public, Visibility::Unlisted]), + ) + .limit(max_results as i64) + .offset(offset as i64) + .select(posts::id) + .load_stream(db_conn) + .await? + .map_ok(|id| SearchResultReference { index, id }) + .try_collect() + .await + })?; Ok(results) } diff --git a/crates/kitsune-service/Cargo.toml b/crates/kitsune-service/Cargo.toml index 932c44f5c..1550a684b 100644 --- a/crates/kitsune-service/Cargo.toml +++ b/crates/kitsune-service/Cargo.toml @@ -15,6 +15,7 @@ bytes = "1.6.0" derive_builder = "0.20.0" diesel = "2.1.5" diesel-async = "0.4.1" +eyre = "0.6.12" futures-util = "0.3.30" garde = { version = "0.18.0", default-features = false, features = [ "derive", @@ -41,7 +42,6 @@ kitsune-search = { path = "../kitsune-search" } kitsune-storage = { path = "../kitsune-storage" } kitsune-url = { path = "../kitsune-url" } kitsune-util = { path = "../kitsune-util" } -miette = "7.2.0" mime = "0.3.17" multiplex-pool = { path = "../../lib/multiplex-pool" } password-hash = { version = "0.5.0", features = ["std"] } diff --git a/crates/kitsune-service/src/account.rs b/crates/kitsune-service/src/account.rs index fe9b779c6..3bbac8f1d 100644 --- a/crates/kitsune-service/src/account.rs +++ b/crates/kitsune-service/src/account.rs @@ -7,8 +7,8 @@ use crate::error::{Error, Result}; use bytes::Bytes; use derive_builder::Builder; use diesel::{ - BoolExpressionMethods, ExpressionMethods, JoinOnDsl, OptionalExtension, QueryDsl, - SelectableHelper, + BoolExpressionMethods, ExpressionMethods, JoinOnDsl, NullableExpressionMethods, + OptionalExtension, QueryDsl, SelectableHelper, }; use diesel_async::RunQueryDsl; use futures_util::{Stream, TryStreamExt}; @@ -16,17 +16,17 @@ use garde::Validate; use iso8601_timestamp::Timestamp; use kitsune_core::traits::{fetcher::AccountFetchOptions, Fetcher, Resolver}; use kitsune_db::{ + function::now, model::{ account::{Account, UpdateAccount}, - follower::Follow as DbFollow, - follower::NewFollow, + follower::{Follow as DbFollow, NewFollow}, notification::NewNotification, post::Post, preference::Preferences, }, post_permission_check::{PermissionCheck, PostPermissionCheckExt}, schema::{accounts, accounts_follows, accounts_preferences, notifications, posts}, - PgPool, + with_connection, PgPool, }; use kitsune_jobs::deliver::{ accept::DeliverAccept, @@ -37,7 +37,6 @@ use kitsune_jobs::deliver::{ }; use kitsune_url::UrlService; use kitsune_util::{sanitize::CleanHtmlExt, try_join}; -use scoped_futures::ScopedFutureExt; use speedy_uuid::Uuid; use std::sync::Arc; use typed_builder::TypedBuilder; @@ -196,25 +195,19 @@ impl AccountService { /// /// Tuple of two account models. First model is the account the followee account, the second model is the followed account pub async fn follow(&self, follow: Follow, notify: bool) -> Result<(Account, Account)> { - let (account, follower) = self - .db_pool - .with_connection(|db_conn| { - async move { - let account_fut = accounts::table - .find(follow.account_id) - .select(Account::as_select()) - .get_result(db_conn); - - let follower_fut = accounts::table - .find(follow.follower_id) - .select(Account::as_select()) - .get_result(db_conn); - - try_join!(account_fut, follower_fut) - } - .scoped() - }) - .await?; + let (account, follower) = with_connection!(self.db_pool, |db_conn| { + let account_fut = accounts::table + .find(follow.account_id) + .select(Account::as_select()) + .get_result(db_conn); + + let follower_fut = accounts::table + .find(follow.follower_id) + .select(Account::as_select()) + .get_result(db_conn); + + try_join!(account_fut, follower_fut) + })?; let id = Uuid::now_v7(); let url = self.url_service.follow_url(id); @@ -232,28 +225,22 @@ impl AccountService { follow_model.approved_at = Some(Timestamp::now_utc()); } - let follow_id = self - .db_pool - .with_connection(|db_conn| { - diesel::insert_into(accounts_follows::table) - .values(follow_model) - .returning(accounts_follows::id) - .get_result(db_conn) - .scoped() - }) - .await?; + let follow_id = with_connection!(self.db_pool, |db_conn| { + diesel::insert_into(accounts_follows::table) + .values(follow_model) + .returning(accounts_follows::id) + .get_result(db_conn) + .await + })?; if account.local { - let preferences = self - .db_pool - .with_connection(|db_conn| { - accounts_preferences::table - .find(follow.account_id) - .select(Preferences::as_select()) - .get_result(db_conn) - .scoped() - }) - .await?; + let preferences = with_connection!(self.db_pool, |db_conn| { + accounts_preferences::table + .find(follow.account_id) + .select(Preferences::as_select()) + .get_result(db_conn) + .await + })?; if (preferences.notify_on_follow && !account.locked) || (preferences.notify_on_follow_request && account.locked) @@ -268,15 +255,13 @@ impl AccountService { .follow(follower.id) }; - self.db_pool - .with_connection(|mut db_conn| { - diesel::insert_into(notifications::table) - .values(notification) - .on_conflict_do_nothing() - .execute(&mut db_conn) - .scoped() - }) - .await?; + with_connection!(self.db_pool, |db_conn| { + diesel::insert_into(notifications::table) + .values(notification) + .on_conflict_do_nothing() + .execute(db_conn) + .await + })?; } } @@ -292,24 +277,18 @@ impl AccountService { /// Get an account by its username and domain pub async fn get(&self, get_user: GetUser<'_>) -> Result> { if let Some(domain) = get_user.domain { - let account = self - .db_pool - .with_connection(|db_conn| { - async move { - accounts::table - .filter( - accounts::username - .eq(get_user.username) - .and(accounts::domain.eq(domain)), - ) - .select(Account::as_select()) - .get_result(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; + let account = with_connection!(self.db_pool, |db_conn| { + accounts::table + .filter( + accounts::username + .eq(get_user.username) + .and(accounts::domain.eq(domain)), + ) + .select(Account::as_select()) + .get_result(db_conn) + .await + .optional() + })?; if let Some(account) = account { return Ok(Some(account)); @@ -336,43 +315,33 @@ impl AccountService { .await .map_err(Error::Fetcher) } else { - self.db_pool - .with_connection(|db_conn| { - async move { - accounts::table - .filter( - accounts::username - .eq(get_user.username) - .and(accounts::local.eq(true)), - ) - .select(Account::as_select()) - .first(db_conn) - .await - .optional() - } - .scoped() - }) - .await - .map_err(Error::from) + with_connection!(self.db_pool, |db_conn| { + accounts::table + .filter( + accounts::username + .eq(get_user.username) + .and(accounts::local.eq(true)), + ) + .select(Account::as_select()) + .first(db_conn) + .await + .optional() + }) + .map_err(Error::from) } } /// Get an account by its ID pub async fn get_by_id(&self, account_id: Uuid) -> Result> { - self.db_pool - .with_connection(|db_conn| { - async move { - accounts::table - .find(account_id) - .select(Account::as_select()) - .get_result(db_conn) - .await - .optional() - } - .scoped() - }) - .await - .map_err(Error::from) + with_connection!(self.db_pool, |db_conn| { + accounts::table + .find(account_id) + .select(Account::as_select()) + .get_result(db_conn) + .await + .optional() + }) + .map_err(Error::from) } /// Get a stream of posts owned by the user @@ -408,14 +377,9 @@ impl AccountService { query = query.filter(posts::id.gt(min_id)).order(posts::id.asc()); } - self.db_pool - .with_connection(|db_conn| { - async move { - Ok::<_, Error>(query.load_stream(db_conn).await?.map_err(Error::from)) - }.scoped() - }) - .await - .map_err(Error::from) + with_connection!(self.db_pool, |db_conn| { + Ok::<_, Error>(query.load_stream(db_conn).await?.map_err(Error::from)) + }) } /// Undo the follow of an account @@ -424,43 +388,31 @@ impl AccountService { /// /// Tuple of two account models. First account is the account that was being followed, second account is the account that was following pub async fn unfollow(&self, unfollow: Unfollow) -> Result<(Account, Account)> { - let (account, follower) = self - .db_pool - .with_connection(|db_conn| { - async move { - let account_fut = accounts::table - .find(unfollow.account_id) - .select(Account::as_select()) - .get_result(db_conn); - - let follower_fut = accounts::table - .find(unfollow.follower_id) - .select(Account::as_select()) - .get_result(db_conn); - - try_join!(account_fut, follower_fut) - } - .scoped() - }) - .await?; - - let follow = self - .db_pool - .with_connection(|db_conn| { - async move { - accounts_follows::table - .filter( - accounts_follows::account_id - .eq(account.id) - .and(accounts_follows::follower_id.eq(follower.id)), - ) - .get_result::(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; + let (account, follower) = with_connection!(self.db_pool, |db_conn| { + let account_fut = accounts::table + .find(unfollow.account_id) + .select(Account::as_select()) + .get_result(db_conn); + + let follower_fut = accounts::table + .find(unfollow.follower_id) + .select(Account::as_select()) + .get_result(db_conn); + + try_join!(account_fut, follower_fut) + })?; + + let follow = with_connection!(self.db_pool, |db_conn| { + accounts_follows::table + .filter( + accounts_follows::account_id + .eq(account.id) + .and(accounts_follows::follower_id.eq(follower.id)), + ) + .get_result::(db_conn) + .await + .optional() + })?; if let Some(follow) = follow { if !account.local { @@ -505,73 +457,52 @@ impl AccountService { query = query.filter(accounts::id.lt(max_id)); } - self.db_pool - .with_connection(|db_conn| { - async move { - Ok::<_, Error>(query.load_stream(db_conn).await?.map_err(Error::from)) - } - .scoped() - }) - .await - .map_err(Error::from) + with_connection!(self.db_pool, |db_conn| { + Ok::<_, Error>(query.load_stream(db_conn).await?.map_err(Error::from)) + }) + .map_err(Error::from) } pub async fn accept_follow_request( &self, follow_request: FollowRequest, ) -> Result> { - let (account, follower) = self - .db_pool - .with_connection(|db_conn| { - async move { - let account_fut = accounts::table - .find(follow_request.account_id) - .select(Account::as_select()) - .get_result(db_conn); - - let follower_fut = accounts::table - .find(follow_request.follower_id) - .select(Account::as_select()) - .get_result(db_conn); - - try_join!(account_fut, follower_fut) - } - .scoped() - }) - .await?; - - let follow = self - .db_pool - .with_connection(|db_conn| { - async move { - accounts_follows::table - .filter( - accounts_follows::account_id - .eq(account.id) - .and(accounts_follows::follower_id.eq(follower.id)), - ) - .get_result::(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; - - if let Some(follow) = follow { - let now = Timestamp::now_utc(); - - self.db_pool - .with_connection(|db_conn| { - diesel::update(&follow) - .set(( - accounts_follows::approved_at.eq(now), - accounts_follows::updated_at.eq(now), - )) - .execute(db_conn) - .scoped() - }) - .await?; + let (account, follower) = with_connection!(self.db_pool, |db_conn| { + let account_fut = accounts::table + .find(follow_request.account_id) + .select(Account::as_select()) + .get_result(db_conn); + + let follower_fut = accounts::table + .find(follow_request.follower_id) + .select(Account::as_select()) + .get_result(db_conn); + + try_join!(account_fut, follower_fut) + })?; + + let follow = with_connection!(self.db_pool, |db_conn| { + accounts_follows::table + .filter( + accounts_follows::account_id + .eq(account.id) + .and(accounts_follows::follower_id.eq(follower.id)), + ) + .get_result::(db_conn) + .await + .optional() + })?; + + if let Some(ref follow) = follow { + with_connection!(self.db_pool, |db_conn| { + diesel::update(follow) + .set(( + accounts_follows::approved_at.eq(now().nullable()), + accounts_follows::updated_at.eq(now()), + )) + .execute(db_conn) + .await + })?; if !account.local { self.job_service @@ -595,49 +526,37 @@ impl AccountService { &self, follow_request: FollowRequest, ) -> Result> { - let (account, follower) = self - .db_pool - .with_connection(|db_conn| { - async move { - let account_fut = accounts::table - .find(follow_request.account_id) - .select(Account::as_select()) - .get_result(db_conn); - - let follower_fut = accounts::table - .find(follow_request.follower_id) - .select(Account::as_select()) - .get_result(db_conn); - - try_join!(account_fut, follower_fut) - } - .scoped() - }) - .await?; - - let follow = self - .db_pool - .with_connection(|db_conn| { - async move { - accounts_follows::table - .filter( - accounts_follows::account_id - .eq(account.id) - .and(accounts_follows::follower_id.eq(follower.id)), - ) - .get_result::(db_conn) - .await - .optional() - } - .scoped() - }) - .await?; + let (account, follower) = with_connection!(self.db_pool, |db_conn| { + let account_fut = accounts::table + .find(follow_request.account_id) + .select(Account::as_select()) + .get_result(db_conn); + + let follower_fut = accounts::table + .find(follow_request.follower_id) + .select(Account::as_select()) + .get_result(db_conn); + + try_join!(account_fut, follower_fut) + })?; + + let follow = with_connection!(self.db_pool, |db_conn| { + accounts_follows::table + .filter( + accounts_follows::account_id + .eq(account.id) + .and(accounts_follows::follower_id.eq(follower.id)), + ) + .get_result::(db_conn) + .await + .optional() + })?; if let Some(follow) = follow { if account.local { - self.db_pool - .with_connection(|db_conn| diesel::delete(&follow).execute(db_conn).scoped()) - .await?; + with_connection!(self.db_pool, |db_conn| { + diesel::delete(&follow).execute(db_conn).await + })?; } else { self.job_service .enqueue( @@ -704,16 +623,13 @@ impl AccountService { }; } - let updated_account: Account = self - .db_pool - .with_connection(|db_conn| { - diesel::update(accounts::table.find(update.account_id)) - .set(changeset) - .returning(Account::as_returning()) - .get_result(db_conn) - .scoped() - }) - .await?; + let updated_account: Account = with_connection!(self.db_pool, |db_conn| { + diesel::update(accounts::table.find(update.account_id)) + .set(changeset) + .returning(Account::as_returning()) + .get_result(db_conn) + .await + })?; self.job_service .enqueue( diff --git a/crates/kitsune-service/src/attachment.rs b/crates/kitsune-service/src/attachment.rs index ae165740f..02a55348d 100644 --- a/crates/kitsune-service/src/attachment.rs +++ b/crates/kitsune-service/src/attachment.rs @@ -279,7 +279,7 @@ mod test { let account_id = db_pool .with_connection(|db_conn| { - async move { Ok::<_, miette::Report>(prepare_db(db_conn).await) }.scoped() + async move { Ok::<_, eyre::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 585830276..c22ca6977 100644 --- a/crates/kitsune-service/src/error.rs +++ b/crates/kitsune-service/src/error.rs @@ -1,8 +1,5 @@ use diesel_async::pooled_connection::bb8; -use std::{ - error::Error as StdError, - fmt::{Debug, Display}, -}; +use std::{error::Error as StdError, fmt::Debug}; use thiserror::Error; pub type BoxError = Box; @@ -71,7 +68,7 @@ pub enum Error { Event(kitsune_messaging::BoxError), #[error(transparent)] - Fetcher(BoxError), + Fetcher(eyre::Report), #[error(transparent)] Http(#[from] http::Error), @@ -101,7 +98,7 @@ pub enum Error { PostProcessing(post_process::BoxError), #[error(transparent)] - Resolver(BoxError), + Resolver(eyre::Report), #[error(transparent)] Rsa(#[from] rsa::Error), @@ -130,15 +127,3 @@ pub enum Error { #[error(transparent)] Validate(#[from] garde::Report), } - -impl From> for Error -where - E: Into + Debug + Display, -{ - fn from(value: kitsune_db::PoolError) -> Self { - match value { - kitsune_db::PoolError::Pool(err) => err.into(), - kitsune_db::PoolError::User(err) => err.into(), - } - } -} diff --git a/crates/kitsune-service/src/prepare.rs b/crates/kitsune-service/src/prepare.rs index 2904e5bdd..f6f605eb9 100644 --- a/crates/kitsune-service/src/prepare.rs +++ b/crates/kitsune-service/src/prepare.rs @@ -45,8 +45,7 @@ where ) .await }) - .await - .into_diagnostic()?; + .await?; RedisCache::builder() .prefix(cache_name) @@ -96,12 +95,11 @@ pub fn storage(config: &storage::Configuration) -> miette::Result::starttls_relay(config.host.as_str()) } else { AsyncSmtpTransport::::relay(config.host.as_str()) - } - .into_diagnostic()?; + }?; let transport = transport_builder .credentials((config.username.as_str(), config.password.as_str()).into()) @@ -126,7 +123,7 @@ pub fn mail_sender( Ok(MailSender::builder() .backend(transport) - .from_mailbox(Mailbox::from_str(config.from_address.as_str()).into_diagnostic()?) + .from_mailbox(Mailbox::from_str(config.from_address.as_str())?) .build()) } @@ -138,7 +135,6 @@ pub async fn messaging(config: &messaging::Configuration) -> miette::Result { let redis_messaging_backend = RedisMessagingBackend::new(&redis_config.url) .await - .into_diagnostic() .wrap_err("Failed to initialise Redis messaging backend")?; MessagingHub::new(redis_messaging_backend) diff --git a/crates/kitsune-wasm-mrf/Cargo.toml b/crates/kitsune-wasm-mrf/Cargo.toml index 68538f723..42bb168d0 100644 --- a/crates/kitsune-wasm-mrf/Cargo.toml +++ b/crates/kitsune-wasm-mrf/Cargo.toml @@ -8,6 +8,7 @@ build = "build.rs" [dependencies] async-trait = "0.1.79" +color-eyre = "0.6.3" derive_more = { version = "1.0.0-beta.6", features = ["from"] } enum_dispatch = "0.3.13" futures-util = { version = "0.3.30", default-features = false, features = [ @@ -15,7 +16,6 @@ futures-util = { version = "0.3.30", default-features = false, features = [ ] } kitsune-config = { path = "../kitsune-config" } kitsune-type = { path = "../kitsune-type" } -miette = "7.2.0" mrf-manifest = { path = "../../lib/mrf-manifest", features = ["decode"] } multiplex-pool = { path = "../../lib/multiplex-pool" } redis = { version = "0.25.2", default-features = false, features = [ diff --git a/crates/kitsune-wasm-mrf/src/error.rs b/crates/kitsune-wasm-mrf/src/error.rs index ff670a613..db7f9690c 100644 --- a/crates/kitsune-wasm-mrf/src/error.rs +++ b/crates/kitsune-wasm-mrf/src/error.rs @@ -1,7 +1,6 @@ -use miette::Diagnostic; use thiserror::Error; -#[derive(Debug, Diagnostic, Error)] +#[derive(Debug, Error)] pub enum Error { #[error(transparent)] Json(#[from] simd_json::Error), diff --git a/crates/kitsune-wasm-mrf/src/kv_storage/fs.rs b/crates/kitsune-wasm-mrf/src/kv_storage/fs.rs index bd098e0f6..9ee6befc9 100644 --- a/crates/kitsune-wasm-mrf/src/kv_storage/fs.rs +++ b/crates/kitsune-wasm-mrf/src/kv_storage/fs.rs @@ -1,5 +1,5 @@ use super::{Backend, BoxError, BucketBackend}; -use miette::IntoDiagnostic; +use color_eyre::eyre; use std::path::Path; pub struct FsBackend { @@ -7,12 +7,12 @@ pub struct FsBackend { } impl FsBackend { - pub fn from_path

(path: P) -> miette::Result + pub fn from_path

(path: P) -> eyre::Result where P: AsRef, { Ok(Self { - inner: sled::open(path).into_diagnostic()?, + inner: sled::open(path)?, }) } } diff --git a/crates/kitsune-wasm-mrf/src/kv_storage/redis.rs b/crates/kitsune-wasm-mrf/src/kv_storage/redis.rs index b4b66fc3f..17ee67da3 100644 --- a/crates/kitsune-wasm-mrf/src/kv_storage/redis.rs +++ b/crates/kitsune-wasm-mrf/src/kv_storage/redis.rs @@ -1,5 +1,5 @@ use super::BoxError; -use miette::IntoDiagnostic; +use color_eyre::eyre; use redis::{aio::ConnectionManager, AsyncCommands}; const REDIS_NAMESPACE: &str = "MRF-KV-STORE"; @@ -9,14 +9,13 @@ pub struct RedisBackend { } impl RedisBackend { - pub async fn from_client(client: redis::Client, pool_size: usize) -> miette::Result { + pub async fn from_client(client: redis::Client, pool_size: usize) -> eyre::Result { let pool = multiplex_pool::Pool::from_producer( || client.get_connection_manager(), pool_size, multiplex_pool::RoundRobinStrategy::default(), ) - .await - .into_diagnostic()?; + .await?; Ok(Self { pool }) } diff --git a/crates/kitsune-wasm-mrf/src/lib.rs b/crates/kitsune-wasm-mrf/src/lib.rs index 5477faffb..cda5bdc6b 100644 --- a/crates/kitsune-wasm-mrf/src/lib.rs +++ b/crates/kitsune-wasm-mrf/src/lib.rs @@ -5,12 +5,12 @@ use self::{ ctx::{construct_store, Context}, mrf_wit::v1::fep::mrf::types::{Direction, Error as MrfError}, }; -use futures_util::{stream::FuturesUnordered, Stream, StreamExt, TryFutureExt, TryStreamExt}; +use color_eyre::{eyre, Section}; +use futures_util::{stream::FuturesUnordered, Stream, TryFutureExt, TryStreamExt}; use kitsune_config::mrf::{ Configuration as MrfConfiguration, FsKvStorage, KvStorage, RedisKvStorage, }; use kitsune_type::ap::Activity; -use miette::{Diagnostic, IntoDiagnostic}; use mrf_manifest::{Manifest, ManifestV1}; use smol_str::SmolStr; use std::{ @@ -20,7 +20,6 @@ use std::{ path::{Path, PathBuf}, sync::Arc, }; -use thiserror::Error; use tokio::fs; use typed_builder::TypedBuilder; use walkdir::WalkDir; @@ -64,14 +63,11 @@ fn load_mrf_module( engine: &Engine, module_path: &Path, bytes: &[u8], -) -> miette::Result, Component)>> { - let component = Component::new(engine, bytes).map_err(|err| { - miette::Report::new(ComponentParseError { - path_help: format!("path to the module: {}", module_path.display()), - advice: "Did you make the WASM file a component via `wasm-tools`?", - }) - .wrap_err(err) - })?; +) -> eyre::Result, Component)>> { + let component = Component::new(engine, bytes) + .map_err(eyre::Report::msg) + .with_note(|| format!("path to the module: {}", module_path.display())) + .suggestion("Did you make the WASM file a component via `wasm-tools`?")?; let Some((manifest, _section_range)) = mrf_manifest::decode(bytes)? else { error!("missing manifest. skipping load."); @@ -93,14 +89,6 @@ pub enum Outcome<'a> { Reject, } -#[derive(Debug, Diagnostic, Error)] -#[error("{path_help}")] -struct ComponentParseError { - path_help: String, - #[help] - advice: &'static str, -} - pub struct MrfModule { pub component: Component, pub config: SmolStr, @@ -121,11 +109,11 @@ impl MrfService { engine: Engine, modules: Vec, storage: kv_storage::BackendDispatch, - ) -> miette::Result { + ) -> eyre::Result { let mut linker = Linker::::new(&engine); - mrf_wit::v1::Mrf::add_to_linker(&mut linker, |ctx| ctx).map_err(miette::Report::msg)?; - wasmtime_wasi::command::add_to_linker(&mut linker).map_err(miette::Report::msg)?; + mrf_wit::v1::Mrf::add_to_linker(&mut linker, |ctx| ctx).map_err(eyre::Report::msg)?; + wasmtime_wasi::command::add_to_linker(&mut linker).map_err(eyre::Report::msg)?; Ok(Self { engine, @@ -136,13 +124,13 @@ impl MrfService { } #[instrument(skip_all, fields(module_dir = %config.module_dir))] - pub async fn from_config(config: &MrfConfiguration) -> miette::Result { + pub async fn from_config(config: &MrfConfiguration) -> eyre::Result { let storage = match config.storage { KvStorage::Fs(FsKvStorage { ref path }) => { kv_storage::FsBackend::from_path(path.as_str())?.into() } KvStorage::Redis(RedisKvStorage { ref url, pool_size }) => { - let client = redis::Client::open(url.as_str()).into_diagnostic()?; + let client = redis::Client::open(url.as_str())?; kv_storage::RedisBackend::from_client(client, pool_size.get()) .await? .into() @@ -155,9 +143,9 @@ impl MrfService { .async_support(true) .wasm_component_model(true); - let engine = Engine::new(&engine_config).map_err(miette::Report::msg)?; + let engine = Engine::new(&engine_config).map_err(eyre::Report::msg)?; let wasm_data_stream = find_mrf_modules(config.module_dir.as_str()) - .map(IntoDiagnostic::into_diagnostic) + .map_err(eyre::Report::from) .and_then(|(module_path, wasm_data)| { let engine = &engine; diff --git a/crates/kitsune-webfinger/Cargo.toml b/crates/kitsune-webfinger/Cargo.toml index 06d9e394e..26dfee60a 100644 --- a/crates/kitsune-webfinger/Cargo.toml +++ b/crates/kitsune-webfinger/Cargo.toml @@ -8,6 +8,7 @@ license.workspace = true [dependencies] async-trait = "0.1.79" autometrics = { version = "1.0.1", default-features = false } +eyre = "0.6.12" futures-util = "0.3.30" http = "1.1.0" kitsune-cache = { path = "../kitsune-cache" } diff --git a/crates/kitsune-webfinger/src/lib.rs b/crates/kitsune-webfinger/src/lib.rs index 581fad62f..cd2c02aa8 100644 --- a/crates/kitsune-webfinger/src/lib.rs +++ b/crates/kitsune-webfinger/src/lib.rs @@ -6,9 +6,8 @@ use autometrics::autometrics; use futures_util::future::{FutureExt, OptionFuture}; use http::{HeaderValue, StatusCode}; use kitsune_cache::{ArcCache, CacheBackend, RedisCache}; -use kitsune_core::consts::USER_AGENT; use kitsune_core::{ - error::BoxError, + consts::USER_AGENT, traits::{resolver::AccountResource, Resolver}, }; use kitsune_http_client::Client; @@ -73,7 +72,7 @@ impl Resolver for Webfinger { &self, username: &str, domain: &str, - ) -> Result, BoxError> { + ) -> eyre::Result> { // XXX: Assigning the arguments to local bindings because the `#[instrument]` attribute // desugars to an `async move {}` block, inside which mutating the function arguments would // upset the borrowck diff --git a/kitsune-cli/Cargo.toml b/kitsune-cli/Cargo.toml index 88d01d873..d0408b62c 100644 --- a/kitsune-cli/Cargo.toml +++ b/kitsune-cli/Cargo.toml @@ -14,13 +14,13 @@ eula = false [dependencies] clap = { version = "4.5.4", features = ["derive", "wrap_help"] } +color-eyre = "0.6.3" diesel = "2.1.5" diesel-async = "0.4.1" dotenvy = "0.15.7" envy = "0.4.2" kitsune-config = { path = "../crates/kitsune-config" } kitsune-db = { path = "../crates/kitsune-db" } -miette = { version = "7.2.0", features = ["fancy"] } serde = { version = "1.0.197", features = ["derive"] } speedy-uuid = { path = "../lib/speedy-uuid" } tokio = { version = "1.37.0", features = ["full"] } diff --git a/kitsune-cli/src/main.rs b/kitsune-cli/src/main.rs index 01690ec8d..add367524 100644 --- a/kitsune-cli/src/main.rs +++ b/kitsune-cli/src/main.rs @@ -1,8 +1,7 @@ use self::{config::Configuration, role::RoleSubcommand}; use clap::{Parser, Subcommand}; -use diesel_async::scoped_futures::ScopedFutureExt; +use color_eyre::eyre::Result; use kitsune_config::database::Configuration as DatabaseConfig; -use miette::{IntoDiagnostic, Result}; mod config; mod role; @@ -24,11 +23,11 @@ struct App { #[tokio::main] async fn main() -> Result<()> { - miette::set_panic_hook(); + color_eyre::install()?; dotenvy::dotenv().ok(); tracing_subscriber::fmt::init(); - let config: Configuration = envy::from_env().into_diagnostic()?; + let config: Configuration = envy::from_env()?; let db_conn = kitsune_db::connect(&DatabaseConfig { url: config.database_url.into(), max_connections: 1, @@ -38,18 +37,10 @@ async fn main() -> Result<()> { let cmd = App::parse(); - db_conn - .with_connection(|db_conn| { - async move { - match cmd.subcommand { - AppSubcommand::Role(cmd) => self::role::handle(cmd, db_conn).await?, - } - - Ok::<_, miette::Report>(()) - } - .scoped() - }) - .await?; + let mut db_conn = db_conn.get().await?; + match cmd.subcommand { + AppSubcommand::Role(cmd) => self::role::handle(cmd, &mut db_conn).await?, + } Ok(()) } diff --git a/kitsune-cli/src/role.rs b/kitsune-cli/src/role.rs index 3595b39ed..290b74da5 100644 --- a/kitsune-cli/src/role.rs +++ b/kitsune-cli/src/role.rs @@ -1,11 +1,11 @@ use clap::{Args, Subcommand, ValueEnum}; +use color_eyre::eyre::Result; use diesel::{BelongingToDsl, BoolExpressionMethods, ExpressionMethods, QueryDsl}; use diesel_async::{AsyncPgConnection, RunQueryDsl}; use kitsune_db::model::{ user::User, user_role::{NewUserRole, Role as DbRole, UserRole}, }; -use miette::{IntoDiagnostic, Result}; use speedy_uuid::Uuid; #[derive(Subcommand)] @@ -57,8 +57,7 @@ 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 - .into_diagnostic()?; + .await?; let new_role = NewUserRole { id: Uuid::now_v7(), @@ -69,8 +68,7 @@ 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 - .into_diagnostic()?; + .await?; Ok(()) } @@ -81,13 +79,11 @@ 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 - .into_diagnostic()?; + .await?; let roles = UserRole::belonging_to(&user) .load::(db_conn) - .await - .into_diagnostic()?; + .await?; println!("User \"{username_str}\" has the following roles:"); for role in roles { @@ -107,8 +103,7 @@ async fn remove_role( let user = users::table .filter(users::username.eq(username_str)) .first::(db_conn) - .await - .into_diagnostic()?; + .await?; diesel::delete( users_roles::table.filter( @@ -118,8 +113,7 @@ async fn remove_role( ), ) .execute(db_conn) - .await - .into_diagnostic()?; + .await?; Ok(()) } diff --git a/kitsune-job-runner/Cargo.toml b/kitsune-job-runner/Cargo.toml index d2ed6e8b4..5fe755fd9 100644 --- a/kitsune-job-runner/Cargo.toml +++ b/kitsune-job-runner/Cargo.toml @@ -26,7 +26,6 @@ kitsune-observability = { path = "../crates/kitsune-observability" } kitsune-service = { path = "../crates/kitsune-service" } kitsune-url = { path = "../crates/kitsune-url" } kitsune-wasm-mrf = { path = "../crates/kitsune-wasm-mrf" } -miette = { version = "7.2.0", features = ["fancy"] } mimalloc = "0.1.39" multiplex-pool = { path = "../lib/multiplex-pool" } redis = { version = "0.25.2", default-features = false, features = [ diff --git a/kitsune-job-runner/src/main.rs b/kitsune-job-runner/src/main.rs index 8194d0da7..0bbb907f8 100644 --- a/kitsune-job-runner/src/main.rs +++ b/kitsune-job-runner/src/main.rs @@ -31,9 +31,8 @@ async fn main() -> miette::Result<()> { kitsune_observability::initialise(env!("CARGO_PKG_NAME"), &config)?; let db_pool = kitsune_db::connect(&config.database).await?; - let job_queue = kitsune_job_runner::prepare_job_queue(db_pool.clone(), &config.job_queue) - .await - .into_diagnostic()?; + let job_queue = + kitsune_job_runner::prepare_job_queue(db_pool.clone(), &config.job_queue).await?; let mrf_service = MrfService::from_config(&config.mrf).await?; let url_service = UrlService::builder() diff --git a/kitsune/Cargo.toml b/kitsune/Cargo.toml index 73c84e6c9..994fc36c0 100644 --- a/kitsune/Cargo.toml +++ b/kitsune/Cargo.toml @@ -69,7 +69,6 @@ kitsune-util = { path = "../crates/kitsune-util" } kitsune-wasm-mrf = { path = "../crates/kitsune-wasm-mrf" } kitsune-webfinger = { path = "../crates/kitsune-webfinger" } metrics = "=0.22.0" -miette = { version = "7.2.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/http/handler/well_known/webfinger.rs b/kitsune/src/http/handler/well_known/webfinger.rs index d3e9b410b..9362a3d70 100644 --- a/kitsune/src/http/handler/well_known/webfinger.rs +++ b/kitsune/src/http/handler/well_known/webfinger.rs @@ -171,7 +171,7 @@ mod tests { redis_test(|redis_pool| async move { let account_id = db_pool .with_connection(|db_conn| { - async move { Ok::<_, miette::Report>(prepare_db(db_conn).await) }.scoped() + async move { Ok::<_, eyre::Report>(prepare_db(db_conn).await) }.scoped() }) .await .unwrap(); @@ -240,7 +240,7 @@ mod tests { .with_connection(|db_conn| { async move { prepare_db(db_conn).await; - Ok::<_, miette::Report>(()) + Ok::<_, eyre::Report>(()) } .scoped() }) diff --git a/kitsune/src/http/mod.rs b/kitsune/src/http/mod.rs index d4b269f6d..c6b1da082 100644 --- a/kitsune/src/http/mod.rs +++ b/kitsune/src/http/mod.rs @@ -85,7 +85,6 @@ 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)) - .into_diagnostic() .wrap_err("Invalid clacks overhead values")?; router = router.layer(clacks_overhead_layer); @@ -114,14 +113,11 @@ pub async fn run( shutdown_signal: crate::signal::Receiver, ) -> miette::Result<()> { let router = create_router(state, &server_config)?; - let listener = TcpListener::bind(("0.0.0.0", server_config.port)) - .await - .into_diagnostic()?; + let listener = TcpListener::bind(("0.0.0.0", server_config.port)).await?; axum::serve(listener, router) .with_graceful_shutdown(shutdown_signal.wait()) - .await - .into_diagnostic()?; + .await?; Ok(()) } diff --git a/kitsune/src/main.rs b/kitsune/src/main.rs index 123e410eb..6c0d19276 100644 --- a/kitsune/src/main.rs +++ b/kitsune/src/main.rs @@ -31,7 +31,6 @@ async fn boot() -> miette::Result<()> { let job_queue = kitsune_job_runner::prepare_job_queue(conn.clone(), &config.job_queue) .await - .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?; @@ -58,8 +57,8 @@ async fn boot() -> miette::Result<()> { )); tokio::select! { - res = server_fut => res.into_diagnostic()??, - res = job_runner_fut => res.into_diagnostic()?, + res = server_fut => res??, + res = job_runner_fut => res?, } Ok(()) @@ -71,8 +70,7 @@ fn main() -> miette::Result<()> { let runtime = tokio::runtime::Builder::new_multi_thread() .enable_all() .thread_stack_size(4 * 1024 * 1024) // Set the stack size to 4MiB - .build() - .into_diagnostic()?; + .build()?; runtime.block_on(boot()) } diff --git a/lib/mrf-manifest/Cargo.toml b/lib/mrf-manifest/Cargo.toml index 9579031ed..75f2ed1c7 100644 --- a/lib/mrf-manifest/Cargo.toml +++ b/lib/mrf-manifest/Cargo.toml @@ -7,7 +7,6 @@ license = "MIT OR Apache-2.0" [dependencies] leb128 = { version = "0.2.5", optional = true } -miette = { version = "7.2.0", optional = true } olpc-cjson = { version = "0.1.3", optional = true } schemars = { version = "0.8.16", features = ["impl_json_schema", "semver"] } semver = { version = "1.0.22", features = ["serde"] } @@ -23,13 +22,7 @@ insta = { version = "1.38.0", default-features = false, features = ["json"] } wat = "1.202.0" [features] -decode = [ - "dep:leb128", - "dep:miette", - "dep:serde_json", - "dep:thiserror", - "dep:wasmparser", -] +decode = ["dep:leb128", "dep:serde_json", "dep:thiserror", "dep:wasmparser"] encode = ["dep:wasm-encoder", "serialise"] serialise = ["dep:olpc-cjson", "dep:serde_json"] diff --git a/lib/mrf-manifest/src/decode.rs b/lib/mrf-manifest/src/decode.rs index 26c93ccc2..d5f20130b 100644 --- a/lib/mrf-manifest/src/decode.rs +++ b/lib/mrf-manifest/src/decode.rs @@ -1,5 +1,4 @@ use crate::{Manifest, SECTION_NAME}; -use miette::Diagnostic; use std::{io, ops::Range}; use thiserror::Error; use wasmparser::Payload; @@ -8,7 +7,7 @@ use wasmparser::Payload; pub type SectionRange = Range; /// Error while decoding the manifest from a WASM module -#[derive(Debug, Diagnostic, Error)] +#[derive(Debug, Error)] pub enum DecodeError { /// Parsing of the JSON manifest failed #[error(transparent)] diff --git a/lib/mrf-tool/Cargo.toml b/lib/mrf-tool/Cargo.toml index 7088deafa..48b58418f 100644 --- a/lib/mrf-tool/Cargo.toml +++ b/lib/mrf-tool/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" [dependencies] clap = { version = "4.5.4", features = ["derive", "wrap_help"] } -miette = { version = "7.2.0", features = ["fancy"] } +color-eyre = "0.6.3" mrf-manifest = { path = "../mrf-manifest", features = [ "decode", "encode", diff --git a/lib/mrf-tool/src/main.rs b/lib/mrf-tool/src/main.rs index 05dca8240..eef0c9259 100644 --- a/lib/mrf-tool/src/main.rs +++ b/lib/mrf-tool/src/main.rs @@ -1,6 +1,6 @@ use self::args::{ManifestSubcommand, ModuleSubcommand, ToolArgs, ToolSubcommand}; use clap::Parser; -use miette::{bail, IntoDiagnostic, Result}; +use color_eyre::{eyre::bail, Result}; use std::{ fs::{self, File}, io::Write, @@ -14,14 +14,14 @@ fn read_manifest(module: &[u8]) -> Result<()> { bail!("missing manifest in module"); }; - let prettified = serde_json::to_string_pretty(&manifest).into_diagnostic()?; + let prettified = serde_json::to_string_pretty(&manifest)?; println!("{prettified}"); Ok(()) } fn remove_manifest(module_path: &Path, output_path: &Path) -> Result<()> { - let module = fs::read(module_path).into_diagnostic()?; + let module = fs::read(module_path)?; let Some((_manifest, section_range)) = mrf_manifest::decode(&module)? else { bail!("missing manifest in module"); }; @@ -30,29 +30,21 @@ fn remove_manifest(module_path: &Path, output_path: &Path) -> Result<()> { .create(true) .truncate(true) .write(true) - .open(output_path) - .into_diagnostic()?; + .open(output_path)?; - module_file - .write_all(&module[..section_range.start]) - .into_diagnostic()?; - module_file - .write_all(&module[section_range.end..]) - .into_diagnostic()?; + module_file.write_all(&module[..section_range.start])?; + module_file.write_all(&module[section_range.end..])?; Ok(()) } fn write_manifest(manifest: &[u8], module_path: &Path) -> Result<()> { // Parse the manifest and re-encode it in canonical JSON - let parsed_manifest = serde_json::from_slice(manifest).into_diagnostic()?; - let custom_section = mrf_manifest::encode(&parsed_manifest).into_diagnostic()?; + let parsed_manifest = serde_json::from_slice(manifest)?; + let custom_section = mrf_manifest::encode(&parsed_manifest)?; - let mut file = File::options() - .append(true) - .open(module_path) - .into_diagnostic()?; - file.write_all(&custom_section).into_diagnostic()?; + let mut file = File::options().append(true).open(module_path)?; + file.write_all(&custom_section)?; Ok(()) } @@ -61,25 +53,25 @@ fn main() -> Result<()> { let args = ToolArgs::parse(); match args.command { ToolSubcommand::Manifest(ManifestSubcommand::Add(args)) => { - let manifest = fs::read(args.manifest_path).into_diagnostic()?; + let manifest = fs::read(args.manifest_path)?; // Only copy if the paths are distinct if args.module_path != args.output { - fs::copy(&args.module_path, &args.output).into_diagnostic()?; + fs::copy(&args.module_path, &args.output)?; } write_manifest(&manifest, &args.output)?; } ToolSubcommand::Manifest(ManifestSubcommand::Read(args)) => { - let data = fs::read(args.module_path).into_diagnostic()?; + let data = fs::read(args.module_path)?; read_manifest(&data)?; } ToolSubcommand::Manifest(ManifestSubcommand::Remove(args)) => { remove_manifest(&args.module_path, &args.output)?; } ToolSubcommand::Module(ModuleSubcommand::Validate(args)) => { - let data = fs::read(args.module_path).into_diagnostic()?; - wasmparser::validate(&data).into_diagnostic()?; + let data = fs::read(args.module_path)?; + wasmparser::validate(&data)?; } }