Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## 2024-07-11 - Route UI print methods to stderr
**Learning:** Routing standard informational/success/error/warning messages to `stderr` allows users to pipe CLI data from `stdout` cleanly without mixing it with UI feedback. This is a common pattern in Unix tools.
**Action:** Ensure `ui.print_*` methods use `eprintln!` instead of `println!`.
## 2024-07-18 - Better nested errors with anyhow's chain

**Learning:** anyhow's default `Debug` format displays errors as a raw numbered list like:
```
Caused by:
0: Failed to send login request
1: client error
```
Which is not very pleasing to the eye or easy to parse for users.

**Action:** Instead of returning `anyhow::Result<()>` from `main()`, we can return `std::process::ExitCode`. This allows us to manually iterate through `anyhow::Error::chain().enumerate()`, displaying the root cause in bold, and cleanly indenting nested causes with a `↳` symbol.
19 changes: 16 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
use anyhow::Result;
use clap::Parser;
use console::style;
use kaji::args::Cli;
use kaji::utils::ui::ERROR;

#[cfg(not(tarpaulin_include))]
#[tokio::main]
async fn main() -> Result<()> {
async fn main() -> std::process::ExitCode {
dotenvy::dotenv().ok();
dotenvy::from_filename(".secrets").ok();
env_logger::init();

let cli = Cli::parse();

kaji::run_app(cli).await
if let Err(err) = kaji::run_app(cli).await {
eprintln!("{} {}", ERROR, style("Error:").red().bold());
for (i, cause) in err.chain().enumerate() {
if i == 0 {
eprintln!(" {}", style(cause).bold());
} else {
eprintln!(" {} {}", style("↳").dim(), cause);
}
}
std::process::ExitCode::FAILURE
} else {
std::process::ExitCode::SUCCESS
}
}