question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

There should be a way to generate warnings when reject is called after resolve

See original GitHub issue

I have lost many hours investigating a problem that arrived due to a promise being resolved and rejected afterward. Here is an example to illustrate the problem I had:

var Promise = require('bluebird')

new Promise(function (resolve, reject) {
    console.log('resolving')
    resolve()

    setTimeout(function () {
        console.log('rejecting')
        reject(new Error())
    }, 0)
}).then(function () {
    console.log('resolved')
}).catch(function (err) {
    console.log('rejected', err)
})

I tried to activate warnings but I din’t get any:

root@874aba35616a:/tmp# BLUEBIRD_WARNINGS=1 node example.js 
resolving
rejecting
resolved
root@874aba35616a:/tmp# 

When I don’t supply an error to reject, I get a warning so I’m confident that the warning mechanism gets activated using the environment variable.

Is there a way to have these warnings? If not can you add this feature? I bet it would save a lot of debugging time.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:8 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
aalexgabicommented, Feb 24, 2017

Here is the code I was debugging:

return new Promise(function (resolve, reject) {
        var csvStream = csv.parse({ delimiter: self.request.separator || ',', columns: true, relax_column_count: true });
        csvStream.on('pipe', function (src) {
            src.on('data', function (data) { self.progressSize += data.length; });
        });
        self.sftpConnection.readAndPipeFile(file.filename, csvStream).catch(function(err){
            err.context = err.context || {};
            err.context.filename = file.filename
            reject(err);
        });
       // BulkPromiseStream is a transformer that waits for promise returned by the mapper to fulfill before acknowledging the fake "write" and emits error on rejection
        csvStream.pipe(new streamTools.BulkPromiseStream(function(slice) {
            return self.processSomeRows(slice).then(function (sliceReport) {
                addReports(report, sliceReport);
                lines += slice.length;
            }).then(function () {
                return self.updateProgress({
                    totalFiles: totalFiles,
                    processedFiles: fileNumber,
                    totalSize: self.totalSize,
                    processedSize: self.progressSize,
                    currentProcessedLines: lines,
                    currentReport: JSON.stringify(report),
                });
            });
        }))
            // we need to add a data consumer in order to finish the stream
            // if we don't, the end event is never called :(
            // it's because BulkPromiseStream is based on Transform
            .on('data', function() {})
            .on('end', resolve)
            .on('error', reject);
        csvStream.on('error', reject);
    })

The bug was in self.processSomeRows that returned too quickly for the last chunk. That resolved the promise but the previous chunk was generating an error later on. This error was totally invisible.

1reaction
benjamingrcommented, Feb 23, 2017

I actually use this fact as a feature (resolving after rejecting)

Read more comments on GitHub >

github_iconTop Results From Across the Web

Promise reject() causes "Uncaught (in promise)" warning
To fix this, make sure that your error code (called by the reject function) does not throw an exception. It should simply return....
Read more >
Error handling with promises - The Modern JavaScript Tutorial
Here's an example: new Promise((resolve, reject) => { resolve("ok"); }). then((result) => { throw new Error("Whoops!"); // rejects the promise ...
Read more >
Promise.resolve() - JavaScript - MDN Web Docs
The Promise.resolve() method "resolves" a given value to a Promise. If the value is a promise, that promise is returned; if the value...
Read more >
Applying a timeout to your promises
Quick tutorial on how to create a generic timeout function that can be applied to any previous existing promise.
Read more >
Promises Cheatsheet - Intermediate JavaScript - Codecademy
Afterwards, it transitions to one of the two states: resolved or rejected . ... The .then() method of a JavaScript Promise object can...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found