quicli icon indicating copy to clipboard operation
quicli copied to clipboard

No context in error output?

Open spease opened this issue 7 years ago • 4 comments

It would appear that context strings don't appear in the error output when using failure::Error. Noticed this long after I replaced some custom code with quicli. I'm not 100% sure this is why the context error isn't showing, but I'm sure enough that I don't want this to get lost.

spease avatar Feb 01 '18 05:02 spease

context strings

I assume you are referring to failure's .context which gives you a Context. Interestingly, the docs for Context says this:

The context is intended to be a human-readable, user-facing explanation for the error that has occurred. The underlying error is not assumed to be end-user-relevant information.

The Display impl for Context only prints the human-readable context, while the Debug impl also prints the underlying error.

I'm quite confused. We are using Display, so you should get the string you gave to .context. In fact, this all we do:

https://github.com/killercup/quicli/blob/789faa77930b6fc97515819647b8167675583d67/src/main_macro.rs#L58

quicli uses context like this, btw:

https://github.com/killercup/quicli/blob/789faa77930b6fc97515819647b8167675583d67/src/fs.rs#L37

killercup avatar Feb 01 '18 08:02 killercup

Perhaps they're referring to the fact that only the top-level context gets printed. For example, if you call .context() multiple times on the same Error object, only the last context message will be printed.

I ran into this today, though not because I called .context() multiple times; I just wanted the program to show the underlying cause of errors instead of just the context message. The workaround I used was to not use the main! macro and instead use

fn main() {
    if let Err(e) = run(Cli::from_args()) {
        eprintln!("error: {}", e);
        for cause in e.causes().skip(1) {
            eprintln!("caused by: {}", cause);
        }
    }
}

fn run(args: Cli) -> Result<()> {
    // main logic
}

This gives errors like

error: couldn't create project directory
caused by: Cannot create a file when that file already exists. (os error 183)

instead of just

couldn't create project directory

I suppose it's possible to keep using the main! macro as it is, and get this behavior by using the with_context method and combining the underlying error with whatever context you want to add, but that's too much work.

Maybe showing the underlying cause would be a better default? I think too much info is better than not enough, in this case.

Seeker14491 avatar Feb 13 '18 08:02 Seeker14491

Thanks for the great explanation, that makes sense!

Maybe showing the underlying cause would be a better default? I think too much info is better than not enough, in this case.

Sounds good. Exit with an error should not be the usual case so I'm fine with being a bit more verbose here :) Can you make a PR with that?

killercup avatar Feb 13 '18 08:02 killercup

Oh, by the way, I opened #44 about showing backtraces recently, which might be related.

killercup avatar Feb 13 '18 08:02 killercup