Reputation: 1628
I'm having a hard time understanding how Promises work. At the base, I understand what resolve
, reject
and .catch ()
are.
However, I am trying to create a Promise function (using Bluebird) that itself uses another Promise function and I want to return a resolve or reject from this nested Promise function. So I have done the following:
FacebookMessengerAPI.js
const request = require("request-promise");
const Prom = require("bluebird");
exports.send = (sender_psid, response) => {
return Prom.try(() => {
if (sender_psid == null || sender_psid == undefined || sender_psid == "") {
console.error("Invalid sender_psid: \t" + sender_psid);
let error = {
code : errorCodes.ERR_INVALID_PARAMETER,
message : "Invalid sender_psid value"
}
return Prom.reject(error); // This works fine
}
if (response == null || response == undefined) {
console.error("Response body is either null or undefined:\t" + response);
let error = {
code : errorCodes.ERR_INVALID_PARAMETER,
message : "Response is either null or undefined"
}
return Prom.reject(error); // This also works fine
}
let options = {
url : appConstants.URL_FACEBOOK_GRAPH_API,
qs : { access_token : appConstants.TOKEN_PAGE_ACCESS },
method : "POST",
body : response,
json : true
};
request(options)
.then((responseBody) => {
console.log("ResponseBody: \t" + responseBody);
}, (rejected) => {
if (rejected.error.error.message) {
let error = {
code : errorCodes.ERR_FB_GRAPH_API,
message : rejected.error.error.message
}
throw error; // This is where things go wrong
}
})
.catch((err) => {
console.error("Error while calling FB Graph API:\n" + err);
let error = {
code : errorCodes.ERR_UNMAPPED_ERROR,
message : err
};
});
});
}
TestApp.js -- the guy that calls this API
"use strict";
const facebookMessengerApi = require("./service/FacebookMessengerApi");
facebookMessengerApi.send(1111,1111).then((resolved) => {
if (resolved) {
console.log("Resolves ==> ",resolved);
}
}, (rejected) => {
if (rejected) {
console.log("Rejected:\t" + someshit);
throw new Error("An err thrown here")
}
}).catch((error) => {
console.error("ERRORIFIED:\n\n" + error);
});
The problem here is, I don't know how to send a Promise object to the parent Promise function from the request
function that itself is a Promise function and is nested inside the parent Promise function.
On resolve / reject of the request function:
When I throw the error by throw new error
, it is caught in the immediate .catch
block of the request
function. It never goes to the actual caller of this API
When I use Prom.reject(error)
, I get unhandled rejection
warning although I don't know exactly where I'm not handling it since I have handled it both in the request
method as well as in the caller of this API. Along with that, the Prom.reject(error)
actually ends up in the .catch()
block of the request
function and not in that of the caller function.
Upvotes: 0
Views: 962
Reputation: 8921
.catch()
on a Promise chain, it recovers the chain
.then()
in the current or parent chain, will now get whatever was returned from the catch statement.<Promise>
: Wait till complete, use value in the next .then()
in the chainNot a promise
: Use the return value as the input for the next .then()
<Exception>
: Not really a return, but will cause it to go to the next catch(e)
, where e
is the exception message<Rejection>
: Comes from a sub-chain having a rejection, or Promise.reject(e)
as a return value. Continue to the next .catch(e)
TL;DR - The output of .then
/ .catch
will always be the output for the next .then()
unless there is an exception or rejection in them. In which case the next .catch()
will be triggered
// Using standard promises
const prBody = _ => {
if (sender_psid == null || sender_psid == undefined || sender_psid == "") {
console.error("Invalid sender_psid: \t" + sender_psid);
let error = {
code : errorCodes.ERR_INVALID_PARAMETER,
message : "Invalid sender_psid value"
}
throw error
}
if (response == null || response == undefined) {
console.error("Response body is either null or undefined:\t" + response);
let error = {
code : errorCodes.ERR_INVALID_PARAMETER,
message : "Response is either null or undefined"
}
throw error // This also works fine
}
let options = {
url : appConstants.URL_FACEBOOK_GRAPH_API,
qs : { access_token : appConstants.TOKEN_PAGE_ACCESS },
method : "POST",
body : response,
json : true
};
// Return a promise which needs to then be resolved for the next thing in the chain to get the data
return request(options)
.then(responseBody => {
console.log("ResponseBody: \t" + responseBody)
return responseBody
})
.catch(errorObj => {
if (!errorObj.error.error.message) return
let error = {
code : errorCodes.ERR_FB_GRAPH_API,
message : rejected.error.error.message
}
throw error; // This is where things go wrong
})
// This is going to be the exception you triggered in the previous catch block
.catch(err => {
console.error("Error while calling FB Graph API:\n" + err);
let error = {
code : errorCodes.ERR_UNMAPPED_ERROR,
message : err
};
});
})
return Promise.resolve()
.then(prBody)
.then(responseBodyORError => {
if (responseBodyORError.error) {return console.log('There was an error, catch simply recover chains')}
// At this point responseBodyORError will only be the response body, since error checking is done
})
Upvotes: 1