Hi All, We have been debating how to design errors raised by future W3C specs to look like. This includes both synchronously and asynchronous APIs. I.e. both thrown exception objects, and asynchronously reported errors reported by for example Promises.
We'd like to get TC39s input on which direction to go. A few of the goals that we've had are: Use the same objects for both synchronous and asynchronous errors. This simplifies error handling, and allows errors to flow through both synchronous and asynchronous call chains. The error objects should test true for |instanceof Error|. I.e. they should either be of type Error, or of a subclass of it. We believe there are situations when it's useful to let code detect what type of error was produced. For example when doing a XMLHttpRequest, it's useful for the caller to be able to know if there was a network error, and it should tell the user to check if they are properly connected to the internet. Or if there was an authentication error and the user should try a different username/password. Or if there was some other error which the website should log and send back to the developer for further analysis. Even in scenarios when a given API can only produce one type of error, it can be valuable to include specific code-readable information in that error. A call chain might call into several different functions that can fail, and it's convenient if you can place an error handler at the top of the call stack which handles errors from multiple different functions. This also applies for asynchronous errors where a chain of Promise.then() calls can surface errors from many different operations to a single error handler at the end of the chain. In situations where it's useful for code to detect which type of error had happened we want to use the same mechanism as for normal JS errors, i.e. the .name property. We do not want to always set .name to something generic like "DOMException" and then add something like .subname. This seems to create a fork in the design where W3C specs behaves different from core JS. And it'd also force authors to check both .name and .subname which seems annoying. It is a little unclear what backwards compatibility constraints that we have. Currently many specifications throw DOMExceptions with a .code and a .name property. The .code is set to a numeric value and the .name property uses the same style of naming as built-in errors. For some of these errors we likely have to make |error instanceof DOMException| test true, and .code return the values they currently return. However we might have the flexibility to use whatever class we want, even for old errors. As long as the class is a subclass of DOMException and thus the instanceof test above tests true. Also, DOMException can very likely be made a subclass of Error. And of course for new errors in specs that have not yet shipped we have full flexibility to do whatever we want. So the question is, what should we do? Option A) Use subclasses of DOMException where web compatibility requires, and direct subclasses of Error otherwise. So we'd add a InvalidStateError class which inherits DOMException. But a new FileIOError could inherit directly from Error. DOMException would inherit Error which means that all errors would still be instanceof Error. Option B) Don't use more subclasses. Instead use DOMException or Error directly. But the .name would contain values like "InvalidStateError" or "FileIOError". DOMException would still inherit Error, which means that all errors would be instanceof Error. Option C is "something else". The advantage of A is that it follows the pattern of current JS errors. The disadvantage is that it clutters the global object with a lot of error constructor functions which doesn't really provide any value as far as I can tell. Another advantage with A is that it gives us a prototype object to stick additional information for certain errors. For example the ConstraintError reported by IndexedDB might in the future provide information about which key there was a constraint validation in. Likewise a NetworkError might want to provide the response body of a 404 result. Such information is possible even using option B, but requires that properties are added on the error object instances, rather than as a getter on the prototype (which is the pattern used by other properties on Error subclasses). I'm personally in favor of option B. It seems simpler while still retaining the ability to check the error type through a single operation, i.e. by checking error.name. But I'm curious to hear others' thoughts. Especially about if there's any good Option Cs. / Jonas _______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

