switch from color-eyre to miette for error reporting
diff --git a/Cargo.lock b/Cargo.lock
index 3207865..c049e97 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -191,6 +191,15 @@ dependencies = [
"windows-link",
]
+[[package]]
+name = "backtrace-ext"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50"
+dependencies = [
+ "backtrace",
+]
+
[[package]]
name = "base64"
version = "0.22.1"
@@ -312,33 +321,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
-[[package]]
-name = "color-eyre"
-version = "0.6.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5920befb47832a6d61ee3a3a846565cfa39b331331e68a3b1d1116630f2f26d"
-dependencies = [
- "backtrace",
- "color-spantrace",
- "eyre",
- "indenter",
- "once_cell",
- "owo-colors",
- "tracing-error",
-]
-
-[[package]]
-name = "color-spantrace"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8b88ea9df13354b55bc7234ebcce36e6ef896aca2e42a15de9e10edce01b427"
-dependencies = [
- "once_cell",
- "owo-colors",
- "tracing-core",
- "tracing-error",
-]
-
[[package]]
name = "colorchoice"
version = "1.0.4"
@@ -502,16 +484,6 @@ dependencies = [
"pin-project-lite",
]
-[[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 = "fastrand"
version = "2.3.0"
@@ -924,12 +896,6 @@ dependencies = [
"icu_properties",
]
-[[package]]
-name = "indenter"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5"
-
[[package]]
name = "indexmap"
version = "2.13.0"
@@ -942,6 +908,12 @@ dependencies = [
"serde_core",
]
+[[package]]
+name = "is_ci"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45"
+
[[package]]
name = "is_executable"
version = "1.0.5"
@@ -1136,6 +1108,36 @@ version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
+[[package]]
+name = "miette"
+version = "7.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7"
+dependencies = [
+ "backtrace",
+ "backtrace-ext",
+ "cfg-if",
+ "miette-derive",
+ "owo-colors",
+ "supports-color",
+ "supports-hyperlinks",
+ "supports-unicode",
+ "terminal_size",
+ "textwrap",
+ "unicode-width 0.1.14",
+]
+
+[[package]]
+name = "miette-derive"
+version = "7.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "mime"
version = "0.3.17"
@@ -1486,9 +1488,9 @@ dependencies = [
"axum",
"clap",
"clap_complete",
- "color-eyre",
"jiff",
"maud",
+ "miette",
"predicates",
"rand",
"serde",
@@ -1989,6 +1991,27 @@ version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+[[package]]
+name = "supports-color"
+version = "3.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6"
+dependencies = [
+ "is_ci",
+]
+
+[[package]]
+name = "supports-hyperlinks"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e396b6523b11ccb83120b115a0b7366de372751aa6edf19844dfb13a6af97e91"
+
+[[package]]
+name = "supports-unicode"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2"
+
[[package]]
name = "syn"
version = "2.0.117"
@@ -2030,12 +2053,32 @@ dependencies = [
"windows-sys 0.61.2",
]
+[[package]]
+name = "terminal_size"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0"
+dependencies = [
+ "rustix",
+ "windows-sys 0.60.2",
+]
+
[[package]]
name = "termtree"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"
+[[package]]
+name = "textwrap"
+version = "0.16.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057"
+dependencies = [
+ "unicode-linebreak",
+ "unicode-width 0.2.2",
+]
+
[[package]]
name = "thiserror"
version = "2.0.18"
@@ -2190,16 +2233,6 @@ dependencies = [
"valuable",
]
-[[package]]
-name = "tracing-error"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db"
-dependencies = [
- "tracing",
- "tracing-subscriber",
-]
-
[[package]]
name = "tracing-log"
version = "0.2.0"
@@ -2247,6 +2280,12 @@ version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
+[[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.25"
@@ -2262,6 +2301,18 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d"
+[[package]]
+name = "unicode-width"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
+
+[[package]]
+name = "unicode-width"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
+
[[package]]
name = "unicode-xid"
version = "0.2.6"
diff --git a/Cargo.toml b/Cargo.toml
index 0936b4d..7d764f5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,7 +9,7 @@ path = "src/bin/ranger/main.rs"
[dependencies]
axum = "*"
-color-eyre = "*"
+miette = { version = "*", features = ["fancy"] }
tracing-subscriber = { version = "*", features = ["env-filter"] }
jiff = { version = "*", features = ["serde"] }
clap = { version = "*", features = ["derive", "env", "unstable-ext"] }
diff --git a/src/bin/ranger/commands/backlog.rs b/src/bin/ranger/commands/backlog.rs
index 2842ee5..eadf3cc 100644
--- a/src/bin/ranger/commands/backlog.rs
+++ b/src/bin/ranger/commands/backlog.rs
@@ -1,7 +1,7 @@
use clap::Subcommand;
use clap_complete::engine::ArgValueCompleter;
-use color_eyre::eyre::Result;
use ranger::db::SqlitePool;
+use ranger::error::RangerError;
use ranger::key;
use ranger::models::{Backlog, State};
use ranger::ops;
@@ -47,7 +47,11 @@ pub enum BacklogCommands {
},
}
-pub async fn run(pool: &SqlitePool, command: BacklogCommands, json: bool) -> Result<()> {
+pub async fn run(
+ pool: &SqlitePool,
+ command: BacklogCommands,
+ json: bool,
+) -> Result<(), RangerError> {
let mut conn = pool.acquire().await?;
match command {
diff --git a/src/bin/ranger/commands/comment.rs b/src/bin/ranger/commands/comment.rs
index 4955c68..01cdbcc 100644
--- a/src/bin/ranger/commands/comment.rs
+++ b/src/bin/ranger/commands/comment.rs
@@ -1,7 +1,7 @@
use clap::Subcommand;
use clap_complete::engine::ArgValueCompleter;
-use color_eyre::eyre::Result;
use ranger::db::SqlitePool;
+use ranger::error::RangerError;
use ranger::ops;
use crate::completions;
@@ -27,7 +27,11 @@ pub enum CommentCommands {
},
}
-pub async fn run(pool: &SqlitePool, command: CommentCommands, json: bool) -> Result<()> {
+pub async fn run(
+ pool: &SqlitePool,
+ command: CommentCommands,
+ json: bool,
+) -> Result<(), RangerError> {
let backlog_scope = super::task::default_backlog_id(pool).await;
let mut conn = pool.acquire().await?;
diff --git a/src/bin/ranger/commands/serve.rs b/src/bin/ranger/commands/serve.rs
index 8320255..44d4c12 100644
--- a/src/bin/ranger/commands/serve.rs
+++ b/src/bin/ranger/commands/serve.rs
@@ -24,7 +24,7 @@ pub async fn run(
pool: &SqlitePool,
port: u16,
default_backlog: Option<String>,
-) -> color_eyre::Result<()> {
+) -> Result<(), ranger::error::RangerError> {
let state = AppState {
pool: pool.clone(),
default_backlog,
@@ -92,7 +92,10 @@ struct TaskView {
tags: Vec<String>,
}
-async fn render_board(state: &AppState, backlog_name: &str) -> color_eyre::Result<Markup> {
+async fn render_board(
+ state: &AppState,
+ backlog_name: &str,
+) -> Result<Markup, ranger::error::RangerError> {
let mut conn = state.pool.acquire().await?;
// Fetch all backlogs for the selector
@@ -326,7 +329,7 @@ async fn to_task_views(
tasks: &[Task],
prefixes: &std::collections::HashMap<String, usize>,
conn: &mut sqlx::pool::PoolConnection<sqlx::Sqlite>,
-) -> color_eyre::Result<Vec<TaskView>> {
+) -> Result<Vec<TaskView>, ranger::error::RangerError> {
let mut views = Vec::with_capacity(tasks.len());
for task in tasks {
let prefix_len = prefixes.get(&task.key).copied().unwrap_or(8);
diff --git a/src/bin/ranger/commands/tag.rs b/src/bin/ranger/commands/tag.rs
index c1ceb06..401e260 100644
--- a/src/bin/ranger/commands/tag.rs
+++ b/src/bin/ranger/commands/tag.rs
@@ -1,6 +1,6 @@
use clap::Subcommand;
-use color_eyre::eyre::Result;
use ranger::db::SqlitePool;
+use ranger::error::RangerError;
use ranger::ops;
use super::task::default_backlog_id;
@@ -28,7 +28,7 @@ pub enum TagCommands {
List,
}
-pub async fn run(pool: &SqlitePool, command: TagCommands, json: bool) -> Result<()> {
+pub async fn run(pool: &SqlitePool, command: TagCommands, json: bool) -> Result<(), RangerError> {
let backlog_scope = default_backlog_id(pool).await;
let mut conn = pool.acquire().await?;
diff --git a/src/bin/ranger/commands/task.rs b/src/bin/ranger/commands/task.rs
index 9d23e63..8bdaf64 100644
--- a/src/bin/ranger/commands/task.rs
+++ b/src/bin/ranger/commands/task.rs
@@ -2,8 +2,8 @@ use std::collections::HashMap;
use clap::{Args, Subcommand};
use clap_complete::engine::ArgValueCompleter;
-use color_eyre::eyre::{Result, bail};
use ranger::db::{SqliteConnection, SqlitePool};
+use ranger::error::RangerError as Error;
use ranger::key;
use ranger::models::{State, Task};
use ranger::ops;
@@ -28,7 +28,7 @@ impl PositionArgs {
self,
conn: &mut SqliteConnection,
backlog_id: Option<i64>,
- ) -> Result<Option<PositionAnchors>> {
+ ) -> Result<Option<PositionAnchors>, Error> {
match (self.before, self.after) {
(None, None) => Ok(None),
(Some(b), None) => {
@@ -168,7 +168,7 @@ pub async fn default_backlog_id(pool: &SqlitePool) -> Option<i64> {
.map(|b| b.id)
}
-pub async fn run(pool: &SqlitePool, command: TaskCommands, json: bool) -> Result<()> {
+pub async fn run(pool: &SqlitePool, command: TaskCommands, json: bool) -> Result<(), Error> {
let backlog_scope = default_backlog_id(pool).await;
match command {
@@ -319,7 +319,9 @@ pub async fn run(pool: &SqlitePool, command: TaskCommands, json: bool) -> Result
task.title
);
}
- None => bail!("--before or --after is required"),
+ None => {
+ return Err(Error::Usage("--before or --after is required".into()));
+ }
}
}
TaskCommands::Delete { key } => {
diff --git a/src/bin/ranger/main.rs b/src/bin/ranger/main.rs
index 71c9664..53b3f10 100644
--- a/src/bin/ranger/main.rs
+++ b/src/bin/ranger/main.rs
@@ -4,6 +4,7 @@ mod output;
use clap::{CommandFactory, Parser, Subcommand};
use clap_complete::engine::ArgValueCompleter;
+use miette::IntoDiagnostic;
use std::path::PathBuf;
use tracing_subscriber::{EnvFilter, fmt, prelude::*};
@@ -71,8 +72,7 @@ fn resolve_db_path(cli_path: Option<PathBuf>) -> PathBuf {
.expect("failed to create data directory")
}
-fn main() -> color_eyre::Result<()> {
- color_eyre::install()?;
+fn main() -> miette::Result<()> {
tracing_subscriber::registry()
.with(fmt::layer())
.with(EnvFilter::from_default_env())
@@ -85,11 +85,12 @@ fn main() -> color_eyre::Result<()> {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
- .build()?
+ .build()
+ .into_diagnostic()?
.block_on(async_main())
}
-async fn async_main() -> color_eyre::Result<()> {
+async fn async_main() -> miette::Result<()> {
let cli = Cli::parse();
let db_path = resolve_db_path(cli.db);
let pool = ranger::db::connect(&db_path).await?;
diff --git a/src/error.rs b/src/error.rs
index e361f0e..851a10e 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,4 +1,4 @@
-#[derive(Debug, thiserror::Error)]
+#[derive(Debug, thiserror::Error, miette::Diagnostic)]
pub enum RangerError {
#[error("no key matching prefix '{0}'")]
KeyNotFound(String),
@@ -11,10 +11,14 @@ pub enum RangerError {
},
#[error("backlog not found: '{0}'")]
BacklogNotFound(String),
+ #[error(transparent)]
+ InvalidState(#[from] crate::models::InvalidStateError),
#[error("database error: {0}")]
Db(#[from] sqlx::Error),
#[error("migration error: {0}")]
Migrate(#[from] sqlx::migrate::MigrateError),
+ #[error("{0}")]
+ Usage(String),
#[error("io error: {0}")]
Io(#[from] std::io::Error),
}