I am still a beginner level programmer and also completely self taught keep that in mind while answering to my post.
I have a ExpressJS server running with an endpoint to send email via postmarkAPI. There are Errors happening some of them are critical and cause server to crash.
I need to answer all requests seamlessly to my frontend since otherwise it would timeout, crash etc.
Here is the error I get:
[39m node:internal/errors:477 [39m ErrorCaptureStackTrace(err); [39m Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client [39m at new NodeError (node:internal/errors:387:5) [39m at ServerResponse.setHeader (node:_http_outgoing:603:11) [39m at ServerResponse.header (/app/node_modules/express/lib/response.js:771:10) [39m at ServerResponse.send (/app/node_modules/express/lib/response.js:170:12) [39m at ServerResponse.json (/app/node_modules/express/lib/response.js:267:15) [39m at ServerResponse.send (/app/node_modules/express/lib/response.js:158:21) [39m at /app/app.js:333:21 [39m at runMicrotasks () [39m at processTicksAndRejections {code: 'ERR_HTTP_HEADERS_SENT'}
I understand that I am sending multiple answers somehow. I think that in some cases then() and catch() are both triggered and therefore I am sending two responds. But I don't know how to fix this.
Here is the Code:
app.post("/mail", (req, res) => {
const authHeader = req.headers.authorization;
//console.log(req.body);
if (authHeader.split(" ")[1] === process.env.TOKEN) {
const from = req.body.mail.from;
const to = req.body.mail.to;
const cc = req.body.mail.cc;
const bcc = req.body.mail.bcc;
const subject = req.body.mail.subject;
const htmlBody = req.body.mail.htmlBody;
const textBody = req.body.mail.textBody;
const replyTo = req.body.mail.replyTo;
const files = req.body.mail.files;
const tag = req.body.mail.tag;
if (files.length > 0) {
let attachments = [];
let promises = [];
for (i in files) {
console.log(i);
let fileName = files[i].name;
let shareLink = files[i].url;
promises.push(
axios
.get(shareLink, {
responseType: "arraybuffer",
})
.catch((err) => {
console.log(err);
})
.then((response) => {
console.log("Downloading & encoding files - Status Code: ", response.status);
console.log(`typeof response.data: ${typeof response.data}`);
const encoded = new Buffer.from(response.data).toString("base64");
attachments.push({
Name: fileName,
Content: encoded,
ContentType: "application/octet-stream",
});
})
);
}
Promise.all(promises)
.then(() => {
sendEmail(
from,
to,
cc,
bcc,
subject,
htmlBody,
textBody,
replyTo,
attachments,
tag
)
.catch((err) => {
console.log(err)
res.send({
error: err,
});
})
.then((response) => {
if (typeof response !== "undefined") {
console.log(`typeof response: ${typeof response}`)
if (typeof response.data !== "undefined") {
res.send({
status: 200,
response: response.data,
});
}
} else {
res.send({
status: 500,
response:
"some error occured in postmark API connection - admin view serverlogs",
});
}
});
})
.catch((err) => {
console.log(err);
});
} else if (files.length < 1) {
var attachments = [];
sendEmail(
from,
to,
cc,
bcc,
subject,
htmlBody,
textBody,
replyTo,
attachments,
tag
)
.catch((err) => {
res.send({
error: err.message,
});
})
.then((response) => {
if (typeof response.data !== "undefined") {
res.send({
status: 200,
response: response.data,
});
} else {
res.send({
status: 500,
response:
"some error occured in postmark API connection - admin view serverlogs",
});
}
});
}
} else {
res.sendStatus(403);
}
});
//==========================================
// FUNCTIONS
//==========================================
async function sendEmail(
from,
to,
cc,
bcc,
subject,
htmlBody,
textBody,
replyTo,
attachments,
tag
) {
var config = {
method: "post",
url: "https://api.postmarkapp.com/email",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
"X-Postmark-Server-Token": process.env.POSTMARK_KEY,
},
data: {
From: from,
To: to,
Cc: cc,
Bcc: bcc,
Subject: subject,
Tag: tag,
HtmlBody: htmlBody,
TextBody: textBody,
ReplyTo: replyTo,
Attachments: attachments,
},
};
const promSendMail = axios(config);
const resMailSent = await promSendMail;
return resMailSent;
}
Any answer and advice that helps me fix this bug or improve my skills or code quality is welcome. Thanks in Advance