Skip to content
This repository has been archived by the owner on Aug 16, 2021. It is now read-only.

Single-line version of DisplayChain #236

Open
dbrgn opened this issue Oct 30, 2017 · 2 comments
Open

Single-line version of DisplayChain #236

dbrgn opened this issue Oct 30, 2017 · 2 comments

Comments

@dbrgn
Copy link

dbrgn commented Oct 30, 2017

Is there a way to get a string representation of the error chain without newlines?

For example, this chain:

Error: decoding error
Caused by: cannot decode message payload
Caused by: could not decrypt bytes

...could be written into a string without newlines like this:

Error: decoding error (caused by: cannot decode message payload (caused by: could not decrypt bytes))

The version with newlines is much easier to read when printing it to the terminal, but there are some use cases where a single line is required without newlines.

A workaround could be:

e.display_chain().to_string().trim().replace("\n", " -> "))

...but that's a bit ugly.

@Yamakaky
Copy link
Contributor

I think you have to iter on the error chain and do the formating yourself

@kaimaera
Copy link

Or derive a custom trait from ChainedError, for instance:

use std::fmt;

#[macro_use]
extern crate error_chain;
use error_chain::ChainedError;

fn main() {
    match make_second_error() {
        Err(e) => {
            eprintln!("Single Line\n{}\n", e.string_chain());
            eprintln!("Multiple Line\n{}", e.display_chain());
        }
        Ok(()) => (),
    }
}
fn make_second_error() -> Result<()> {
    make_error().chain_err(|| "doing something else")?;
    Ok(())
}

fn make_error() -> Result<()> {
    make_io_error().chain_err(|| "doing something")?;
    Ok(())
}

fn make_io_error() -> Result<()> {
    return Err(::std::io::Error::new(::std::io::ErrorKind::Other, "some io error").into());
}

error_chain! {
    foreign_links {
        Io(::std::io::Error);
    }
}

trait ChainedString: ChainedError + Send + 'static {
    fn string_chain<'a>(&'a self) -> DisplayString<'a, Self>;
}

impl ChainedString for Error {
    fn string_chain<'a>(&'a self) -> DisplayString<'a, Self> {
        DisplayString(self)
    }
}

struct DisplayString<'a, T: ChainedError + 'a + ?Sized>(&'a T);

impl<'a, T: ChainedError + 'a + ?Sized> fmt::Display for DisplayString<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)?;
        for err in self.0.iter().skip(1) {
            write!(f, ": {}", err)?;
        }
        Ok(())
    }
}

which produces:

Single Line
doing something else: doing something: some io error

Multiple Line
Error: doing something else
Caused by: doing something
Caused by: some io error

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants