-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Background information #1
Comments
Even though a promise is in a rejected state, it's important to know how it got to be in that state:
I'd argue it's only the later that should be treated as unintentional and logged/reported etc. Any errors that are part of the application contract could be communicated by returning rejected promises and handled like any regular value. |
I strongly disagree. The entire point of exceptions (and thus their asynchronous analog, rejections) is that they're outside your control. You can't partition your failure cases into "intentional" and "unintentional." As another counterpoint, I'd like to offer the following strawman statement:
This seems like a large burden to place on users. |
I definitely don't think we should differentiate based on "intentional" vs. "unintentional" errors. To some extent all errors are "intentional" - |
I agree with @domenic and @ForbesLindesay: interpretation and handling of exceptions is ultimately an application developer decision, and the parallel between unhandled exceptions and rejections is, imho, way too strong to ignore. Any uncaught exception that makes its way to the host environment causes a loud stack trace, regardless of the intent with which it was originally thrown. I think we should mimic that behavior with unhandled rejections as closely as possible. The trick is, as @domenic pointed out in Statement of the issue, that unhandled rejections have a temporal component: At what point do they become crash-worthy? Yay, it's a halting problem for promises: "Write a promise debugger that tells me if this rejected promise is ever handled". |
I have a method that does a database query, and rejects the returned promise with a My rejection handler should translate the database level The pattern here would essentially be: query().then(null, function(error){
if(error && error.name === "NotFoundError"){
return rejected(new ResourceMissingError());
}
throw error;
}); If the |
It wouldn't and it shouldn't. If your application later handles that ResourceMissingError and sends a 404 (or similar) to the user it won't get tracked as an unhandled rejection. If you didn't handle it then it would've happened at an unexpected time and should be logged as unexpected. |
I believe part of the disconnect here is what exactly is a promise? To me, a promise is a thing that will eventually end up in one of two states with one of two results. Others seem to be thinking about a promise as a thing that will eventually resolve or throw an error. An example would be a web request. When you have a It seems that most of the proposals here are operating on the assumption that one will always be handling the results of a promise immediately, not storing them off for later processing. If promises are intended to be resolved or crash, then the above example would have to be changed to return something like a |
There is a lot of discussion about treating promise errors like exceptions, but promises are very different from exceptions. Exceptions unwind the call stack, promises are more akin to an
What is being proposed is that if my code simply leaves off the |
@Zoltu I strongly disagree. https://blog.domenic.me/youre-missing-the-point-of-promises/ |
@Zoltu If you plan to cache promises, I think it is a good practise to always explicitly state how errors are handled - if you don't do it, you'll get an For your use case, you can still do let prefetched = fetch('http://google.com');
prefetched.then(null, function ignoreErrors(){});
// later
prefetched.then(…, …); // actually deal with it |
I believe that forcing the developer to write catches for every promise he ever interacts with is a very poor experience. Also, I may return a promise from a function that the user doesn't need to know the result to. A library may expose a method, It feels like the proponents of unhandled rejection reporting by default have pigeon holed promises into a very specific usage pattern. Unfortunately, this usage pattern does not allow one to fully leverage the power that promises bring. It is unrealistic to write a truly promise-driven application when you have to have code like this: constructor() {
this.foo = doStuff();
this.foo.catch(...);
this.bar = thirdPartyLibrary(this.foo);
this.bar.catch(...);
this.zip = this.method(this.foo);
// don't need to catch here, this.method sets up a catch
}
method(somePromise) {
somePromise.catch(...);
let temp = new Promise(...);
temp.catch(...);
return somePromise || temp;
} The point that the above example is making is that it is very difficult to discern provenance of every variable, especially in JavaScript, so I have to put guard catch clauses anywhere I see a new promise entering my system and, unless I assume third party library authors are guarding everywhere as well, then I have to guard against all of my return promises (they may be given to a third party library) and all of my incoming promises. I understand that debugging code is hard, I don't think castrating an excellent feature is the right solution to that problem though. Looking at other languages with promises/futures, which ones treat unhandled rejections as errors like this? I believe Dart does, but the others I have looked into don't appear to. C++11 doesn't, Scala doesn't, .NET doesn't, I don't believe Java does, Python doesn't appear to, I'm not trying to appeal to authority here, but I believe if one wants to go against everyone who has gone down this path there should be a very strong reason for it, and I am not hearing that in any of these discussions. That all being said, a choice does need to be made as to the direction of JavaScript. If JavaScript wants to be seen as an enterprise application development language then it needs powerful standardized asynchronous tools such as Promises (as implemented in other languages, catering to veteran developers looking to author complex applications). If JavaScript wants to remain a scripting language for the web, then the benefit of making it harder to screw up probably outweighs the advantage of powerful programming constructs. |
This is rough and not spec-worthy, but is meant to give us a common starting point for future issues.
Terminology
then
orcatch
call), we say that the rejection has now been "handled later." Notably, this could happen several seconds later.Statement of the issue
catch
blocks, then you can be sure that nobody will ever handle them, and the runtime knows your program should crash.Sample Code
The text was updated successfully, but these errors were encountered: