summaryrefslogtreecommitdiffstats
path: root/libimagutil
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2016-02-07 00:01:36 +0100
committerMatthias Beyer <mail@beyermatthias.de>2016-02-11 15:48:41 +0100
commitd8ae741f31af2ac719bd089c249a034486ef242a (patch)
tree81d26aefa96c25acc2903919dae8ea50816153bd /libimagutil
parent78cda89524743630eb5a218c1a44b272697337e1 (diff)
Add error tracing utility
Diffstat (limited to 'libimagutil')
-rw-r--r--libimagutil/src/lib.rs1
-rw-r--r--libimagutil/src/trace.rs46
2 files changed, 47 insertions, 0 deletions
diff --git a/libimagutil/src/lib.rs b/libimagutil/src/lib.rs
index 788f28cb..a7586143 100644
--- a/libimagutil/src/lib.rs
+++ b/libimagutil/src/lib.rs
@@ -2,4 +2,5 @@
extern crate regex;
pub mod key_value_split;
+pub mod trace;
pub mod variants;
diff --git a/libimagutil/src/trace.rs b/libimagutil/src/trace.rs
new file mode 100644
index 00000000..af949e7f
--- /dev/null
+++ b/libimagutil/src/trace.rs
@@ -0,0 +1,46 @@
+use std::error::Error;
+use std::io::Write;
+use std::io::stderr;
+
+pub fn trace_error(e: &Error) {
+ print_trace_maxdepth(count_error_causes(e), e, ::std::u64::MAX);
+ write!(stderr(), "");
+}
+
+pub fn trace_error_maxdepth(e: &Error, max: u64) {
+ let n = count_error_causes(e);
+ write!(stderr(), "{}/{} Levels of errors will be printed", (if max > n { n } else { max }), n);
+ print_trace_maxdepth(n, e, max);
+ write!(stderr(), "");
+}
+
+pub fn trace_error_dbg(e: &Error) {
+ print_trace_dbg(0, e);
+}
+
+/// Helper function for `trace_error()` and `trace_error_maxdepth()`.
+///
+/// Returns the cause of the last processed error in the recursion, so `None` if all errors where
+/// processed.
+fn print_trace_maxdepth(idx: u64, e: &Error, max: u64) -> Option<&Error> {
+ if e.cause().is_some() && idx > 0 {
+ print_trace_maxdepth(idx - 1, e.cause().unwrap(), max);
+ write!(stderr(), " -- caused:");
+ }
+ write!(stderr(), "Error {:>4} : {}", idx, e.description());
+ e.cause()
+}
+
+/// Count errors in Error::cause() recursively
+fn count_error_causes(e: &Error) -> u64 {
+ 1 + if e.cause().is_some() { count_error_causes(e.cause().unwrap()) } else { 0 }
+}
+
+fn print_trace_dbg(idx: u64, e: &Error) {
+ debug!("Error {:>4} : {}", idx, e.description());
+ if e.cause().is_some() {
+ debug!(" -- caused by:");
+ print_trace_dbg(idx + 1, e.cause().unwrap());
+ }
+}
+