I come across a Promise warning about an inextricable chain of promises ("a promise was created in the handler, but was not returned from it"). I'm new to Promises, and I suspect I'm using event-based thinking when I shouldn't be. But I'm not sure how to proceed. All this is in the nodejs project.
I am interacting with the ZWave server to turn on and off the light sources. This interaction takes the form of sending HTTP requests to the server that manages the ZWave network. I use Promises due to asynchronous interaction with HTTP.
At one level of my program, I defined the following class method:
ZWave.prototype.onOff = function (nodeNumber, turnOn) { var self = this; var level = turnOn ? 255 : 0; return new Promise(function (resolve, reject) { self.requestAsync(sprintf('/Run/devices[%d].instances[0].commandClasses[0x20].Set(%d)', nodeNumber, level)) .then(function (value) { resolve(value == 'null'); }) .catch(function (error) { reject(error); }); });
};
The requestAsync method method is the one that actually interacts with the ZWave server. Conceptually, in onOff (), I try to turn on a specific light identified by this .nodeNumber, either turn it on or off, and then return the result of this query.
onOff () is called from a method of the Switch class that represents a particular light, as follows:
this.onOff = function( turnOn ) { var state = turnOn ? 'ON' : 'OFF'; var self = this; zWave.onOff( this.nodeNumber, turnOn ) .then( function() { winston.info( sprintf( '%s: turned %s', self.displayName, state ) ); return true; } ) .catch( function( error ) { winston.info( sprintf( '%s: error while turning %s => %s', self.displayName, state, error ) ); return false; } ); }
The operations "return true" and "return false" are my attempt to end the Promise chain. But it does not work, and I still get a warning.
This puts me as a concrete example of a more general problem: how do you move from a Promise-based model to a traditional blocking code?
Edit
Answering a few questions from the comments ...
I am using bluebird.
zWave.onOff () returns a promise.
Switch.onOff () and zWave.onOff () are different functions in separate classes.
All code is javascript.
Edit 2
I believe that I implemented the jfriend00 suggestions, although I included the .catch () handler in the zWave.onOff () function, but I still get the same unhandled promise error:
ZWave.prototype.onOff = function (nodeNumber, turnOn) { var self = this; var level = turnOn ? 255 : 0; return self.requestAsync( sprintf( '/Run/devices[%d].instances[0].commandClasses[0x20].Set(%d)', nodeNumber, level ) ) .then( function( value ) { resolve( value == 'null' ); } ) .catch( function( error ) { reject( error ); } ); };
and
// function inside Switch class this.onOff = function( turnOn ) { var state = turnOn ? 'ON' : 'OFF'; var self = this; return zWave.onOff( this.nodeNumber, turnOn ).reflect() .then( function() { winston.info( sprintf( '%s: turned %s', self.displayName, state ) ); return true; } ) .catch( function( error ) { winston.info( sprintf( '%s: error while turning %s => %s', self.displayName, state, error ) ); return false; } ); }
Here is the warning text:
Warning: a promise was created in the handler, but was not returned from it on ZWave.requestAsync (/home/mark/XmasLights/zWaveRequest.js:19:12) in ZWave.onOff (/home/mark/XmasLights/zWaveRequest.js: 93:17) at onOff (/home/mark/XmasLights/switch.js:42:22) at updateCron (/home/mark/XmasLights/switch.js:80:18) at dailyUpdate (/ home / mark / XmasLights / app.js: 196: 21) in /home/mark/XmasLights/app.js:134:58 on processImmediate [like _immediateCallback] (timers.js: 383: 17)
Sorry to run when formatting the warning, I cannot get stackoverflow to correctly separate lines.