mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
This partially revertsed8f347fe6from #7183 and6277d7d5f2from #7201. # Output how it was merged for v47 (#7066) ``` Error: Cloud Hypervisor exited with the following chain of errors: 0: Error booting VM 1: The VM could not boot 2: Error manipulating firmware file 3: No such file or directory (os error 2) Debug Info: VmBoot(VmBoot(FirmwareFile(Os { code: 2, kind: NotFound, message: "No such file or directory" }))) ``` # Output after #7183 and #7201 ``` cloud-hypervisor: 31.385730ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:27 -- Error: Cloud Hypervisor exited with the following chain of errors: cloud-hypervisor: 31.417961ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:39 -- 0: Error booting VM cloud-hypervisor: 31.448078ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:39 -- 1: The VM could not boot cloud-hypervisor: 31.486711ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:39 -- 2: Error manipulating firmware file cloud-hypervisor: 31.513331ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:39 -- 3: No such file or directory (os error 2) cloud-hypervisor: 31.548037ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:44 -- cloud-hypervisor: 31.568045ms: <main> ERROR:/home/pschuster/dev/cloud-hypervisor/src/lib.rs:45 -- Debug Info: VmBoot(VmBoot(FirmwareFile(Os { code: 2, kind: NotFound, message: "No such file or directory" }))) ``` The "proper logger" has indeed the advantage that messages can be gracefully redirected to log files etc. However, this makes the error message hardly readable. Therefore, I propose to use error!() only for runtime errors messages but not a pretty-printed version of those. Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de> On-behalf-of: SAP philipp.schuster@sap.com
47 lines
1.5 KiB
Rust
47 lines
1.5 KiB
Rust
// Copyright © 2025 Cyberus Technology GmbH
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use std::error::Error;
|
|
|
|
use log::error;
|
|
|
|
/// Prints a chain of errors to the user in a consistent manner.
|
|
/// The user will see a clear chain of errors, followed by debug output
|
|
/// for opening issues.
|
|
pub fn cli_print_error_chain<'a>(
|
|
top_error: &'a (dyn Error + 'static),
|
|
component: &str,
|
|
// Function optionally returning the display representation of an error.
|
|
display_modifier: impl Fn(
|
|
/* level */ usize,
|
|
/*indention */ usize,
|
|
&'a (dyn Error + 'static),
|
|
) -> Option<String>,
|
|
) {
|
|
// Debug info.
|
|
error!("Fatal error: {top_error:?}");
|
|
|
|
eprint!("Error: {component} exited with the following ");
|
|
if top_error.source().is_none() {
|
|
eprintln!("error:");
|
|
eprintln!(" {top_error}");
|
|
} else {
|
|
eprintln!("chain of errors:");
|
|
std::iter::successors(Some(top_error), |sub_error| {
|
|
// Dereference necessary to mitigate rustc compiler bug.
|
|
// See <https://github.com/rust-lang/rust/issues/141673>
|
|
(*sub_error).source()
|
|
})
|
|
.enumerate()
|
|
.for_each(|(level, error)| {
|
|
// Special case: handling of HTTP Server responses in ch-remote
|
|
if let Some(message) = display_modifier(level, 2, error) {
|
|
eprintln!("{message}");
|
|
} else {
|
|
eprintln!(" {level}: {error}");
|
|
}
|
|
});
|
|
}
|
|
}
|