Reputation: 428
When I make a request to my endpoint I need to get a successful response only if the email is sent! otherwise, it should throw an error:
myendpoint.js
router.post("/", upload.none(), async (req, res) => {
try {
let body = JSON.parse(req.body.contact);
await getDb("messages").insertOne({
name: body.name,
email: body.email,
phone: body.phone,
subject: body.subject,
message: body.message,
});
await sendEmail(body);
res.send(
JSON.stringify({
success: true,
msg: "Message has been sent successfully",
})
);
} catch (err) {
res.send(JSON.stringify({ success: false, msg: err }));
}
});
sendEmail.js
const sendEmail = async function (props) {
const transporter = nodemailer.createTransport({
service: process.env.EMAIL_SERVICE,
host: process.env.EMAIL_HOST,
auth: {
user: process.env.EMAIL_FROM,
pass: process.env.EMAIL_PASS,
},
});
const mailOptions = {
from: process.env.EMAIL_FROM,
to: process.env.EMAIL_TO,
name: props.name,
email: props.email,
phone: props.phone,
subject: props.subject,
text: props.message,
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
throw new Error("Message did Not send!");
}
});
};
the problem is before "await sendEmail(body);" ends and i get the error, i get the "Message has been sent successfully" and then server crashes! what am i missing?
Upvotes: 1
Views: 3218
Reputation: 8546
const handler = async ({ subject, name, body, contact }) => {
const transporter = nodemailer.createTransport({
service: "zoho",
// Disable MFA here to prevent authentication failed: https://accounts.zoho.com/home#multiTFA/modes
// ********************* OR *****************
// set up Application-Specific Passwords here: https://accounts.zoho.com/home#security/device_logins
auth: { user: process.env.NEXT_PUBLIC_EMAIL_ADDRESS, pass: process.env.NEXT_PUBLIC_EMAIL_PASSWORD },
});
return transporter
.sendMail(mailOptions({ subject, name, body, contact }))
.then((info) => {
if (process.env.NODE_ENV !== "production") console.log("Email sent: " + info.response);
return true;
})
.catch((err) => {
if (process.env.NODE_ENV !== "production") console.log("error sending mail", err);
return false;
});
};
Upvotes: 2
Reputation: 177
Hello you can change your Transporter sendMail to :
return await transporter.sendMail(mailOptions);
Or You can Use Promise.
Upvotes: 1
Reputation: 3431
Check document function sendMail from nodemailer at here
If callback argument is not set then the method returns a Promise object. Nodemailer itself does not use Promises internally but it wraps the return into a Promise for convenience.
const sendEmail = async function (props) {
const transporter = nodemailer.createTransport({
service: process.env.EMAIL_SERVICE,
host: process.env.EMAIL_HOST,
auth: {
user: process.env.EMAIL_FROM,
pass: process.env.EMAIL_PASS,
},
});
const mailOptions = {
from: process.env.EMAIL_FROM,
to: process.env.EMAIL_TO,
name: props.name,
email: props.email,
phone: props.phone,
subject: props.subject,
text: props.message,
};
// remove callback and function sendMail will return a Promise
return transporter.sendMail(mailOptions);
};
Upvotes: 2