Using promisified request module, i want to get the body attribute of the response. Not sure if I should use a Promise try.
So which one is correct here ?
A. Without Promise.try
request.getAsync("http://example.com")
.then( x => x.body )
.tap( x=> console.log('body:',x) )
B. With Promise.try
request.getAsync("http://example.com")
.then( x => Promise.try( () => x.body ) )
.tap( x=> console.log('body:',x) )
After the first element of a promise chain, an error is guaranteed to throw down the chain's error path and become available to be caught by a .then(null, errorHandler)
or .catch(errorHandler)
.
Therefore there is no point using Bluebird's Promise.try()
other than to get a chain reliably started. Doing so will just bulk up your code and make it less efficient.
How about inner chains?
This is more interesting. Inner chains are commonly used to allow access to earlier results via closure. Flattened chains lose this ability.
Consider :
request.getAsync("http://example.com")
.then( x => {
return untrusted.method().then((y) => other.method(x, y));
});
The inner chain has its own starter, untrusted.method()
, which may cause failure in one of two ways:
A throw is unavoidable (without addressing untrusted.method()
), though the thrown error will be catchable in the outer chain.
But a non-thenable can be guarded against. You can write :
request.getAsync("http://example.com")
.then(x => {
return Promise.try(untrusted.method).then((y) => other.method(x, y) );
});
Now Promise.try()
ensures the inner chain has a reliable start. Promise.try(untrusted.method)
is guaranteed to be thenable.
As a bonus, an error thrown by untrusted.method()
is now catchable in the outer chain or the inner chain, which can be useful, particularly for error recovery.
Promise.resolve(untrusted.method())
would similarly protect against a non-thenable being returned but would not allow a synchronous throw to be caught within the inner chain.
So in summary,
Promise.try()
.Promise.try()
.Promise.try()
to guarantee an inner chain's reliable start.