I am working on my newsletter project using Mailchimp API, it works but I can't redirect to a failure page if the status code is not 200, the browser says localhost refused to connect meanwhile success page redirection works great. here's my code:
app.post("/", async(req, res, next)=>{
const {fName, lName, email} = req.body.user;
const response = await mailchimp.lists.addListMember("List_ID", {
email_address: email,
status: "subscribed",
merge_fields:{
FNAME: fName,
LNAME: lName,
},
});
if(res.statusCode === 200){
res.sendFile(__dirname "/success.html");
}
else{
res.sendFile(__dirname "/failure.html");
}
});
CodePudding user response:
Maybe you can use "try..catch" to catch unexpected error. See below.
try {
if(res.statusCode === 200){
res.sendFile(__dirname "/success.html");
}
else{
res.sendFile(__dirname "/failure.html");
}
} catch (err) {
res.sendFile(__dirname "/failure.html");
}
CodePudding user response:
First of all using async
with express
, if anything in your async
function throws express won't get notified about that which would result in an error like:
localhost refused to connect
A quick and dirty solution would be to warp your whole body of the async
function into a try .. catch
block. But that's tedious and you might still miss some side conditions.
So instead you would want to create a wrapper for that which could look that way: (There are probably better implementations for an express async wrapper)
function asyncExpressWrapper(fn) {
// return the wrapping middelware be used.
return async (req, res, next) => {
try {
// call the actual middelware you passed
await fn(req, res, next);
} catch (err) {
// will catch any error thrown in fn
next(err)
}
}
}
And use it that way:
app.post("/", asyncExpressWrapper(async(req, res, next) => {
const {
fName,
lName,
email
} = req.body.user;
const response = await mailchimp.lists.addListMember("List_ID", {
email_address: email,
status: "subscribed",
merge_fields: {
FNAME: fName,
LNAME: lName,
},
});
if (response.statusCode === 200) {
res.sendFile(__dirname "/success.html");
} else {
res.sendFile(__dirname "/failure.html");
}
}));
Now that will solve the localhost refused to connect
problem, and express will tell you which error you didn't handle.
Besides that your res.statusCode === 200
will check the express response statusCode which at that point is always true, if response
has a statusCode
it has to be response.statusCode === 200
.
Now your __dirname "/failure.html"
likely still is not shown, as the Promise returned by mailchimp.lists.addListMember
likely rejects in the error case. So you needd also a try ... catch
in your middleware:
app.post("/", asyncExpressWrapper(async(req, res, next) => {
const {
fName,
lName,
email
} = req.body.user;
try {
const response = await mailchimp.lists.addListMember("List_ID", {
email_address: email,
status: "subscribed",
merge_fields: {
FNAME: fName,
LNAME: lName,
},
});
// you probably don't need that if-else at all and only emit
// success here, but I don't know mailchimp.lists.addListMember
// so that's up to you to figure out.
if (response.statusCode === 200) {
res.sendFile(__dirname "/success.html");
} else {
res.sendFile(__dirname "/failure.html");
}
} catch(err) {
res.sendFile(__dirname "/failure.html");
}
}));