Implement the Error Cause proposal
Categories
(Core :: JavaScript Engine, enhancement, P3)
Tracking
()
Tracking | Status | |
---|---|---|
firefox91 | --- | fixed |
People
(Reporter: alex.fdm, Assigned: anba)
References
(Blocks 2 open bugs, )
Details
(Keywords: dev-doc-complete)
Attachments
(7 files)
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review |
The proposal is currently in Stage 2.
Updated•4 years ago
|
Updated•4 years ago
|
Assignee | ||
Comment 2•4 years ago
|
||
Updated•4 years ago
|
Assignee | ||
Comment 3•4 years ago
|
||
Depends on D115230
Assignee | ||
Comment 4•4 years ago
|
||
Depends on D115231
Assignee | ||
Comment 5•4 years ago
|
||
Depends on D115234
Assignee | ||
Comment 6•4 years ago
|
||
@evilpie noticed that the EXNTYPE_SLOT
is no longer needed and instead can
be replaced by comparing an error's class against ErrorObject::classes
.
Drive-by change:
- Strengthened the assertion in
ErrorObject::init
to test againsttype < JSEXN_WARN
.
Assignee | ||
Comment 7•4 years ago
|
||
Depends on D115235
Assignee | ||
Comment 8•4 years ago
|
||
Assignee | ||
Comment 9•4 years ago
|
||
Gentle review ping for https://phabricator.services.mozilla.com/D115353.
Assignee | ||
Updated•4 years ago
|
Comment 10•4 years ago
|
||
Comment 11•4 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/577a29a4b7ba
https://hg.mozilla.org/mozilla-central/rev/be1e81db2f62
https://hg.mozilla.org/mozilla-central/rev/728e142d5ecd
https://hg.mozilla.org/mozilla-central/rev/8704e075c2db
https://hg.mozilla.org/mozilla-central/rev/d3caa5a42a29
https://hg.mozilla.org/mozilla-central/rev/55cb6696ad3b
https://hg.mozilla.org/mozilla-central/rev/3093ea3c4c4b
Comment 12•4 years ago
•
|
||
FF91 Docs work for this is can be tracked in https://github.com/mdn/content/issues/6714
Some questions:
- Is this available release 91 build or is it restricted (e.g. to nightly)?
- I can see from the spec and this example how this is generally supposed to be used. Essentially you catch the original error(s) and throw a new error with a more useful message, passing the original error as the
cause
.
What I don't really understand from the examples is why that is useful. The examples still use the original message for differentiating the particular error from all errors that might be raised (or they could, with a trivial restructure), so why do you care what the original error object was? By contrast I can see how a custom error is useful, because it is simple to write handlers that check the error type and we can do this without having to contrive unique message names.
Further, the spec and example talk about cause
giving us an agreed way to identify the cause of an error in order to improve the presentation of the cause by developer tools. But the cause doesn't have to be the original error object - it can be anything. So if I decide to put some string "This is the cause" in there how is this in any way useful for tools to present the error cause?
My "guess" from https://bugzilla.mozilla.org/show_bug.cgi?id=1711887 is that we expect this to always contain the original error. So what this does is allow us to create a daisy chain of errors. Effectively a bit like unwinding a stack trace.
I hope that makes some sense - I can see what it does and how you might use it, but the examples feel very contrived and don't seem to add anything much over just having useful error messages. What am I missing?
Assignee | ||
Comment 13•4 years ago
|
||
(In reply to Hamish Willee from comment #12)
Some questions:
- Is this available release 91 build or is it restricted (e.g. to nightly)?
It will be available in the release build.
- I can see from the spec and this example how this is generally supposed to be used. Essentially you catch the original error(s) and throw a new error with a more useful message, passing the original error as the
cause
.What I don't really understand from the examples is why that is useful. The examples still use the original message for differentiating the particular error from all errors that might be raised (or they could, with a trivial restructure), so why do you care what the original error object was? By contrast I can see how a custom error is useful, because it is simple to write handlers that check the error type and we can do this without having to contrive unique message names.
For example it can be used to throw your own custom Error
type. Let's say there's a fallible call into some framework code and for some reason it's necessary to wrap any errors into a different Error
object. Using the cause
proposal, it's possible to wrap an error while still keeping the original error (and its stack trace).
try {
framework();
} catch (err) {
throw MyError("new message", {cause: err});
}
Further, the spec and example talk about
cause
giving us an agreed way to identify the cause of an error in order to improve the presentation of the cause by developer tools. But the cause doesn't have to be the original error object - it can be anything. So if I decide to put some string "This is the cause" in there how is this in any way useful for tools to present the error cause?
JavaScript allows to throw
any value and therefore it's not possible to restrict the type of the cause
property to be an object. If the cause
property doesn't provide any useful information, Devtools can simply choose to ignore the property.
// The |throw| statement can throw any value.
throw "string";
throw 123;
throw undefined;
My "guess" from https://bugzilla.mozilla.org/show_bug.cgi?id=1711887 is that we expect this to always contain the original error. So what this does is allow us to create a daisy chain of errors. Effectively a bit like unwinding a stack trace.
I hope that makes some sense - I can see what it does and how you might use it, but the examples feel very contrived and don't seem to add anything much over just having useful error messages. What am I missing?
I think the feature will most likely end up being used when:
- You don't control the original error's message.
- Or you have to throw a specific error type.
Comment 14•4 years ago
|
||
Thanks very much. I have finished the draft docs: https://github.com/mdn/content/pull/7316 - comments welcome.
The doc says that you can use the cause in a custom event too. Is that correct?
Updated•4 years ago
|
Assignee | ||
Comment 15•4 years ago
|
||
The doc says that you can use the cause in a custom event too. Is that correct?
Did you mean "custom error"? In that case, yes, it's possible to use cause
there, too. The cause
property is processed in the Error
constructor, so any subclass just needs to pass the options in the super
call:
class MyError extends Error {
constructor(/* some arguments */) {
// Needs to pass both |message| and |options| to install the "cause" property.
super(message, options);
}
}
It won't work if the code is written like:
class MyError extends Error {
constructor(/* some arguments */) {
// Only passes |message| because that used to be the only argument for Error.
// This code needs to be updated to pass |options|, too.
super(message);
}
}
Comment 16•4 years ago
|
||
Thanks very much - just what I needed.
Description
•