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

Support 'compound errors' #1

Open
brson opened this issue Jul 11, 2016 · 11 comments
Open

Support 'compound errors' #1

brson opened this issue Jul 11, 2016 · 11 comments

Comments

@brson
Copy link
Contributor

brson commented Jul 11, 2016

Right now error-chain expects errors to be a linear sequence of errors, but twice recently I've encountered situations where I had two errors at the same time and had to figure out something to do with them. In practice one could likely have been considered the cause and the other fallout from the original error, but this relationship wasn't reflected in their structure.

Examples:

  • During some asynchronous I/O I stashed an error away in a callback because the client library didn't allow me to pass it through as context. Later, after the I/O failed with another error, I had to decide whether to return the original error or the one that it created as fallout.
  • During cleanup on an error path, subsequent operations may themselves fail, producing multiple errors.

It would be good to have a standard way to handle these situations. I imagine a CompoundError(primary, secondary) variant that stashes the lesser error with secondary perhaps being a Vec.

@golddranks
Copy link
Contributor

Just linking this here: https://www.reddit.com/r/rust/comments/4xryih/hey_rustaceans_got_an_easy_question_ask_here/d6r0j2u/ In this case, "Some environmental variables not set!" would be the primary error, and a Vec of the individual errors for every environmental variable being the set of the secondary errors.

@Ralith
Copy link

Ralith commented Nov 11, 2016

I ended up building something like this for a config file parser that I wanted to get as many errors as possible from for similar reasons to @golddranks, i.e. minimize the number of round trips a user with invalid input has to make to fix everything. In my case the error is wholly defined by the sub-errors, since any one of them would be an adequate justification for failure.

@sfackler
Copy link
Contributor

sfackler commented Dec 9, 2016

Java added a concept of "suppressed" exceptions that are attached to a "parent" exception for this kind of use case in 1.7: https://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html#addSuppressed(java.lang.Throwable).

@flying-sheep
Copy link

yeah, i’d like something like that too, see #137 for my use case

@TedDriggs
Copy link
Contributor

As far as the API for this goes, I wonder if it could be something like the Join struct in the futures crate?

The error_chain crate might want to expose a Compound<T> type, and then opt-in create a Error::Compound variant for the caller if requested. It does beg the question of what iter() means at that point: Does it traverse breadth-first or depth-first?

@golddranks
Copy link
Contributor

golddranks commented Jun 16, 2017

Btw. I was bitten by this today again.

I keep noticing that I need "combined" errors the most when I'm doing something user-faced. Let's say that there's 5 independent things we could do, and they could independently fail. Computationally it's of course the best to fail fast, but I think it's good UI design to try them all even if one would fail, and then report all the errors, so the user get's a better picture of all the things that need fixing, instead of fixing and error and finding another.

I wonder if there would be some use to an "error accumulator API". It could "absorb" multiple Results, and then give back the Oks at once, or a combined error object.

@golddranks
Copy link
Contributor

I'd love to see a push towards a solution of this, maybe as a part of the Libz Bliz effort? Or is that more about evaluation?

@Yamakaky
Copy link
Contributor

If you want to try a PR/suggest how to do it, feel free!

@golddranks
Copy link
Contributor

I'll see if I can manage to have the time to do that during the next week. No hard promises!

@Yamakaky
Copy link
Contributor

I see what you mean ;)

@TedDriggs
Copy link
Contributor

FWIW, I recently had to implement this for a project of mine. I ended up with ErrorKind::Multiple, which had a Vec<Error> instance as its contents. Iteration was shallow, but Error::flatten(self) -> Error did a depth-first traversal to create one flat list of errors, with context cloned to each item. This enabled a crate to have an efficient representation for as long as possible, and to then convert to a flat error list immediately before display to a user.

faern pushed a commit to faern/error-chain that referenced this issue Sep 3, 2017
…enabled

Fix tests for cache backtrace enabled
AndyGauge pushed a commit that referenced this issue May 7, 2019
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

7 participants