fix: doctor lists errors on one line with the hint last
This commit is contained in:
1 parent
272f2d30ab
commit
77ae14ed1d
2 files changed
+56
-3
No files matched your search
+27
-3
@@ -4,6 +4,7 @@ use std::path::Path;
|
|||||||
use anyhow::{Result, bail};
|
use anyhow::{Result, bail};
|
||||||
|
|
||||||
use crate::config;
|
use crate::config;
|
||||||
|
use crate::error::one_line;
|
||||||
use crate::niri;
|
use crate::niri;
|
||||||
use crate::wayland::Wayland;
|
use crate::wayland::Wayland;
|
||||||
|
|
||||||
@@ -96,7 +97,10 @@ pub fn check_niri(version: Result<String>) -> Check {
|
|||||||
match version {
|
match version {
|
||||||
Err(e) => check(
|
Err(e) => check(
|
||||||
Level::Warn,
|
Level::Warn,
|
||||||
format!("niri IPC unavailable ({e:#}); using the first output for `screen`"),
|
format!(
|
||||||
|
"niri IPC unavailable ({}); using the first output for `screen`",
|
||||||
|
one_line(&e)
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Ok(v) => match niri::parse_version(&v) {
|
Ok(v) => match niri::parse_version(&v) {
|
||||||
Some(found) if found == niri::IPC_VERSION => check(Level::Ok, format!("niri {v}")),
|
Some(found) if found == niri::IPC_VERSION => check(Level::Ok, format!("niri {v}")),
|
||||||
@@ -117,7 +121,7 @@ pub fn check_config(path: &Path) -> Check {
|
|||||||
Level::Ok,
|
Level::Ok,
|
||||||
format!("config {} not found, using defaults", path.display()),
|
format!("config {} not found, using defaults", path.display()),
|
||||||
),
|
),
|
||||||
Err(e) => check(Level::Fail, format!("config: {e:#}")),
|
Err(e) => check(Level::Fail, format!("config: {}", one_line(&e))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +159,7 @@ pub fn run() -> Result<()> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => checks.push(check(Level::Fail, format!("wayland: {e:#}"))),
|
Err(e) => checks.push(check(Level::Fail, format!("wayland: {}", one_line(&e)))),
|
||||||
}
|
}
|
||||||
checks.push(check_niri(niri::version()));
|
checks.push(check_niri(niri::version()));
|
||||||
let config_path = config::default_path();
|
let config_path = config::default_path();
|
||||||
@@ -246,6 +250,26 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn broken_config_fails_with_hint_last() {
|
||||||
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
let path = dir.path().join("config.toml");
|
||||||
|
std::fs::write(&path, "[save]\ndirectory = \n").unwrap();
|
||||||
|
let c = check_config(&path);
|
||||||
|
assert_eq!(c.level, Level::Fail);
|
||||||
|
assert!(
|
||||||
|
c.text.starts_with("config: invalid config file"),
|
||||||
|
"{}",
|
||||||
|
c.text
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
c.text
|
||||||
|
.ends_with("(hint: fix the file or delete it to use the defaults)"),
|
||||||
|
"{}",
|
||||||
|
c.text
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn save_dir_checks() {
|
fn save_dir_checks() {
|
||||||
let dir = tempfile::tempdir().unwrap();
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
|||||||
@@ -58,6 +58,22 @@ pub fn render(err: &anyhow::Error, log: Option<&Path>) -> String {
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The error on one line, hint last: `msg: cause (hint: ...)`. For places
|
||||||
|
/// that list several results, like `valw doctor`.
|
||||||
|
pub fn one_line(err: &anyhow::Error) -> String {
|
||||||
|
let hint = err.downcast_ref::<Hint>().map(|h| h.0.as_str());
|
||||||
|
let messages: Vec<String> = err
|
||||||
|
.chain()
|
||||||
|
.map(|e| e.to_string())
|
||||||
|
.filter(|m| Some(m.as_str()) != hint)
|
||||||
|
.collect();
|
||||||
|
let mut out = messages.join(": ");
|
||||||
|
if let Some(hint) = hint {
|
||||||
|
out.push_str(&format!(" (hint: {hint})"));
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -101,6 +117,19 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_line_puts_hint_last() {
|
||||||
|
let err = Err::<(), _>(anyhow!("Could not find wayland compositor"))
|
||||||
|
.context("could not connect to the Wayland compositor")
|
||||||
|
.hint("valw needs a Wayland session; is WAYLAND_DISPLAY set?")
|
||||||
|
.unwrap_err();
|
||||||
|
assert_eq!(
|
||||||
|
one_line(&err),
|
||||||
|
"could not connect to the Wayland compositor: Could not find wayland compositor \
|
||||||
|
(hint: valw needs a Wayland session; is WAYLAND_DISPLAY set?)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cancelled_is_detectable() {
|
fn cancelled_is_detectable() {
|
||||||
let err = anyhow::Error::new(Cancelled).context("region selection");
|
let err = anyhow::Error::new(Cancelled).context("region selection");
|
||||||
|
|||||||
Reference in new issue
Block a user