opensource icon indicating copy to clipboard operation
opensource copied to clipboard

Sendgrid Node API email timeout without error

Open MorenoMdz opened this issue 3 years ago • 0 comments

We have had this weird behavior where some emails are never sent, we did not have a timeout set in our SendGrid initialization, so some emails never got sent but did not throw any errors either. The only clue we had is that some of the cloud functions were timing out at 5000ms for some reason, we assumed SendGrid never responded to the call and it would shut down the cloud function.

After some research we added a timeout of 10000ms to the sender method, it will now throw in some emails with a timeout error.

Why is 10 seconds not enough, the email content is a pretty small text, the same email addresses received emails before as this is a daily cycle that sends email to our clients, it just randomly time out and the email is never sent.

async function sendMail(templateName, msg, worker = {}) {
  const { analytics } = require("../../config/analytics");
  try {
    const API_KEY = functions.config().sendgrid.key;
    sgMail.setApiKey(API_KEY);
    // https://github.com/sendgrid/sendgrid-nodejs/tree/main/docs/use-cases
    sgMail.setTimeout(20000);

    const largePayload = sizeOf(msg.dynamic_template_data) / 1024 > 31;
    const templateData = largePayload
      ? "Message payload is too large"
      : msg.dynamic_template_data;

    if (msg.to) {
      console.log(`Sending email to ${msg.to}`);
      const track = {
        userId: msg.to,
        event: "Email Sent",
        properties: {
          templateName,
          templateData
        }
      };
      analytics.track(track);
    }

    msg.templateId = functions.config().sendgrid[templateName];
    const response = await sgMail.send(msg);
    console.log(`DEBUG: ${msg.to} Sendgrid response:`, response);
    return response;
  } catch (error) {
    if (error.response && error.response.body) {
      console.error(error.response.body);
    } else {
      console.log(error);
    }
    Sentry.withScope(function (scope) {
      !isEmpty(worker) &&
        scope.setUser({
          firstName: worker.firstName,
          lastName: worker.lastName,
          id: worker.uid,
          email: worker.email,
          phoneNumber: worker.phoneNumber
        });
      Sentry.captureException(error);
    });
    throw new functions.https.HttpsError(
      "internal",
      msg.to ? `Error sending email to ${msg.to}` : "Error sending email",
      error
    );
  }
}

MorenoMdz avatar Jun 23 '22 14:06 MorenoMdz