Reputation: 27266
This is obviously a SSCCE. I have the following (jsFiddle here):
<html>
<body>
<input id='file-dlg' type='file'/>
<br/>
<button id='submit' type='button'>submit</button>
<script>
document.getElementById('file-dlg').addEventListener('change', storeAPromise);
var p;
function storeAPromise() {
p = new Promise(function executor(resolve, reject) {
try {
throw new Error('snafu');
} catch(e) {
reject(e);
}
});
};
document.getElementById('submit').onclick = function() {
p.then(function() {}, function reject(e) {
console.error('some problem happenned', e);
});
};
</script>
</body>
</html>
When the user is using the file dialog to select a file, I expect nothing at all to be printed on the console as the Error
is caught and the promise's reject
function is called. In contrast, I am expecting the error to appear on the console with the description "some error happened" only when I click the "submit" button.
Yet, this is not what I observe. As soon as the user selects a file with the dialog I see on the console:
Uncaught (in promise) Error: snafu(…)
When the user presses the "submit" button I do see the expected log line "some problem happened" but I don't understand why I also see the earlier "Uncaught (in promise)" log line when the user selects a file with the file dialog. I also don't see why the error is described as "Uncaught" given that I catch (unconditionally) all exceptions and simple invoke the reject
function.
Upvotes: 5
Views: 27021
Reputation: 664185
It's not an uncaught exception, it's an uncaught rejection. Promises should not be left dangling in the rejected state with no error callback attached - that's why the console is warning you about this. You can also handle these cases in your application with the unhandledrejection
event.
If you want to handle the error later (install the handler when the user clicks the button, which might be never!), you still will need to immediately install an empty callback (that explicitly ignores the error) to suppress the warning.
var p = Promise.resolve();
document.getElementById('file-dlg').addEventListener('change', function createPromise() {
p = new Promise(function executor(resolve, reject) {
throw new Error('snafu');
});
p.catch(e => {/* ignore for now */});
});
document.getElementById('submit').addEventListener('click', function addErrorHandler() {
p.catch(function onReject(e) {
console.error('some problem happened', e);
});
});
Notice that you don't need that try
/catch
- the promise constructor will catch all exceptions from the executor by default already.
Upvotes: 15