tc39/proposal-error-cause

Comparison with existing solutions

iainireland opened this issue · 6 comments

As the FAQ acknowledges, this can be implemented using custom error classes. The main value is therefore helping to coordinate debug tooling. Has a survey been done of existing tooling that could benefit from this proposal? If so, does this cover the important use cases?

Do we have examples in the wild of problems that would be solved by this proposal?

Most of the time, re-thrown errors need to be augmented with contextual information. An API like this would allow that to work without mutating caught errors. They simply accumulate in a chain with additional contextual information.

This feature has been implemented in C#, Java, Python, and many more.

Also JavaScript libraries: verror with weekly 16,880,330 downloads, @netflix/nerror with weekly 103,560 downloads.

Most examples in the field will be similar to what we have in the README doc, and can be summarized as follows:

function highLevelOp() {
  try {
    lowLevelOp();
  } catch (lowLevelCause) {
    throw new HighLevelError(message, lowLevelCause); // init an error with the cause
  }
}

Sorry, let me make my question more precise. What problems does this proposal solve that are not better solved by libraries?

verror and nerror have a number of features that are not covered by this proposal: in particular, printf-style arguments for the message. This is only possible because the VError constructor puts the cause parameter first, which would not be a backwards-compatible change for Error. So even if this proposal was accepted, developers who want printf-style arguments for errors would still have to use an error library.

What I'm hoping for is more information about this part of the FAQ:

While there are lots of ways to achieve the behavior of the proposal, if the cause property is explicitly defined by the language, debug tooling can reliably use this info rather than contracting with developers to construct an error properly.

Can you give a concrete example of debug tooling that could "reliably use this info", and how that tooling would benefit from this proposal?

I really like this proposal, it's a nice addition to the language. It's missing a few things that are in VError (e.g. #14) which I think would be beneficial and make it more complete.

Can you give a concrete example of debug tooling that could "reliably use this info", and how that tooling would benefit from this proposal?

The dev tools in browsers could use this to give better stack traces for thrown errors, as is done in languages like Java:

Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: Exception thrown
	at com.example.TraceTest.doSomething(TraceTest.java:13)
	at com.example.TraceTest.run(TraceTest.java:6)
	at com.example.TraceTest.main(TraceTest.java:22)
Caused by: java.lang.RuntimeException: Exception thrown
	at com.example.TraceTest.throwAnException(TraceTest.java:18)
	at com.example.TraceTest.doSomething(TraceTest.java:11)
	... 2 more

I see that as the primary benefit of this proposal. It's well-trodden ground from other languages.

It's necessary to do this in the language rather than a library because the built-in devtools in browsers can't coordinate around a feature in a third-party library.

This is a great addition to the standard as it enables the entire ecosystem to build on top of a single implementation of .cause, currently some projects have been reluctant to support eg. VError#cause as it hasn't been seen as relevant to them as they themselves don't use VError

It does however pose some compatibility issues for the mentioned ones: #31

Closing this as it is already been explained. Feel free to re-open if there is anything new to discuss.