Skip to content

Sendgrid Node API email timeout without error #29

@MorenoMdz

Description

@MorenoMdz

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
    );
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions