Sendgrid-nodejs: Working SendGrid.mail() code fails without error in AWS Lambda environment

Created on 14 Dec 2020  路  10Comments  路  Source: sendgrid/sendgrid-nodejs

Issue Summary

Running the basic test code for sending mail through the SendGrid node API works locally but fails without errors in a Lambda function.

Steps to Reproduce

Take the code from https://app.sendgrid.com/guide/integrate/langs/nodejs and get it working locally. Then upload to an AWS Lambda function (follow the steps here to upload to Lambda). Configure an arbitrary test event and run the function with any logging you want.

Code Snippet

exports.handler = async (event) => {

    const sgMail = require('@sendgrid/mail');
    //sgMail.setApiKey(process.env.SENDGRID_API_KEY);
    sgMail.setApiKey('my_api_key'); //Tested with environment variable and hardcoded, same result for both
    const msg = {
      to: '[email protected]',
      from: '[email protected]',
      subject: 'Sending with SendGrid is fun',
      text: 'and easy to do anywhere, even with Node.js',
      html: '<strong>and easy to do anywhere, even with Node.js</strong>',
    };

    sgMail
        .send(msg)
        .then(() => {
            console.log('Email sent');
            const response = {
                statusCode: 200,
            };
            return response;
        })
        .catch((error) => {
            console.error(error);
            const response = {
                statusCode: 400,
            };
            return response;
        });

    console.error("You shouldn't be here");
    const response = {
        statusCode: 300,
    };
    return response;
};

Exception/Log

I haven't been able to get anything of interest appearing with console.log's, all that shows up is the
I also tried adding a try/catch around the whole send/then/catch and it still shows the "You shouldn't be here" error

START RequestId: 7391f0e6-a3cf-4434-87d5-b2f89d53f628 Version: $LATEST
2020-12-14T14:48:15.399Z    d4e01174-9186-46e9-b757-c92c4dc0a5fb    ERROR   You shouldn't be here
END RequestId: 7391f0e6-a3cf-4434-87d5-b2f89d53f628
REPORT RequestId: 7391f0e6-a3cf-4434-87d5-b2f89d53f628  Duration: 823.19 ms Billed Duration: 824 ms Memory Size: 128 MB Max Memory Used: 99 MB  Init Duration: 636.84 ms    

Technical details:

  • sendgrid-nodejs version: 6.3.1
  • node version: 10.x (same as running locally, also tested with 12.x)

Any help would be greatly appreciated :) This problem has been persisting exactly the same for a few days now despite minor changes to the code, but running locally still works

EDIT: Very weird update to add to this, I just changed the Lambda's trigger which caused it to have a brief (~10 min) latency period before outputting CloudWatch logs again. During this period I added something to the S3 bucket it triggers on and received the email! But that run didn't produce any logs to CloudWatch. And now that logging seems to be up and running again I haven't gotten another email through.

waiting for feedback question

Most helpful comment

I'm experiencing this same issue on my dev machine (macOS) using "@sendgrid/mail": "^7.4.0".

Things have been working fine for about a month, and now, without any changes to the code to send emails, it's failing inconsistently; sometimes, an error is caught, but I often get to the line of code to send an email, and nothing happens. Literally.

Code snippet

 try {
      const message = {
        from: postApplyEmail,
        subject: subject,
        to: template.to,
        html: renderedEmail,
      };
      logger.info(`Sending email to ${message.to}...`);
      const [response] = await sgMail.send(message);
      logger.info("Email sent.");
    } catch (error) {
      logger.err(error, true);
    }

Note that "Email Sent" is never written, and neither is the error from the catch block.

The one somewhat useful error I've received

[2021-01-11T20:36:21.574Z] ERROR: ResponseError: Unauthorized
    at node_modules/@sendgrid/client/src/classes/client.js:146:29
    at processTicksAndRejections (internal/process/task_queues.js:93:5) {
  code: 401,
  response: {
    headers: {
      server: 'nginx',
      date: 'Mon, 11 Jan 2021 20:36:21 GMT',
      'content-type': 'application/json',
      'content-length': '88',
      connection: 'close',
      'access-control-allow-origin': 'https://sendgrid.api-docs.io',
      'access-control-allow-methods': 'POST',
      'access-control-allow-headers': 'Authorization, Content-Type, On-behalf-of, x-sg-elas-acl',
      'access-control-max-age': '600',
      'x-no-cors-reason': 'https://sendgrid.com/docs/Classroom/Basics/API/cors.html'
    },
    body: { errors: [Array] }
  }
}

I've tried going back and forth between the async/await and promise APIs, and nothing works. I could only get this message once (no success in getting this logged to the CLI because it seems the client ignores any callback passed to it and didn't respect the try/catch block).

I've tested my token to ensure it's correct using Curl. My server is also using cors, so no idea why the x-no-cors-reason header is set. I've been banging my head against the wall for about a day now without much progress.

Any updates on this issue would be ideal.

All 10 comments

Hello @Ulthran,

The code looks good to me. Since you have changed configuration outside of the above source code and it worked (albeit just one time) without changing the source, it appears the issue is not with the helper library code. That said, it's been a while since you posted this, are you still experiencing the same issue?

With best regards,

Elmer

Hi Elmer,

Thanks for the response! I'm still stuck on the same issue but haven't looked into it much more since posting this.

Are you able to reproduce it?

I'm experiencing this same issue on my dev machine (macOS) using "@sendgrid/mail": "^7.4.0".

Things have been working fine for about a month, and now, without any changes to the code to send emails, it's failing inconsistently; sometimes, an error is caught, but I often get to the line of code to send an email, and nothing happens. Literally.

Code snippet

 try {
      const message = {
        from: postApplyEmail,
        subject: subject,
        to: template.to,
        html: renderedEmail,
      };
      logger.info(`Sending email to ${message.to}...`);
      const [response] = await sgMail.send(message);
      logger.info("Email sent.");
    } catch (error) {
      logger.err(error, true);
    }

Note that "Email Sent" is never written, and neither is the error from the catch block.

The one somewhat useful error I've received

[2021-01-11T20:36:21.574Z] ERROR: ResponseError: Unauthorized
    at node_modules/@sendgrid/client/src/classes/client.js:146:29
    at processTicksAndRejections (internal/process/task_queues.js:93:5) {
  code: 401,
  response: {
    headers: {
      server: 'nginx',
      date: 'Mon, 11 Jan 2021 20:36:21 GMT',
      'content-type': 'application/json',
      'content-length': '88',
      connection: 'close',
      'access-control-allow-origin': 'https://sendgrid.api-docs.io',
      'access-control-allow-methods': 'POST',
      'access-control-allow-headers': 'Authorization, Content-Type, On-behalf-of, x-sg-elas-acl',
      'access-control-max-age': '600',
      'x-no-cors-reason': 'https://sendgrid.com/docs/Classroom/Basics/API/cors.html'
    },
    body: { errors: [Array] }
  }
}

I've tried going back and forth between the async/await and promise APIs, and nothing works. I could only get this message once (no success in getting this logged to the CLI because it seems the client ignores any callback passed to it and didn't respect the try/catch block).

I've tested my token to ensure it's correct using Curl. My server is also using cors, so no idea why the x-no-cors-reason header is set. I've been banging my head against the wall for about a day now without much progress.

Any updates on this issue would be ideal.

I'm still working on reproducing this @Ulthran, in the meantime, have you checked out this blog post?

@iAmWillShepherd Since that's an authentication error, I would double check the environment variable in AWS.

Thanks @thinkingserious, I read through that blog post and it's suggesting all the steps as I've done them (except that my lambda is triggered off an S3 event rather than the API). Let me know if I can be any help in reproducing the issue.

I appear to be getting the same CORS error using the sendgrid api from my Nodejs server running on DigitalOcean. Please let me know if perhaps I can be helpful in reproducing the issue.

EDIT: I've realized it may not be a CORS error at all. Could be just an auth error as you point out.

I am having the same issue, and it does not happen always. I am looking for a solution if at all possible. It is strange this error is occurring.
ResponseError: Unauthorized
at node_modules/@sendgrid/client/src/classes/client.js:146:29
at processTicksAndRejections (internal/process/task_queues.js:97:5) {
code: 401,
response: {
headers: {
server: 'nginx',
date: 'Thu, 28 Jan 2021 19:51:15 GMT',
'content-type': 'application/json',
'content-length': '76',
connection: 'close',
'access-control-allow-origin': 'https://sendgrid.api-docs.io',
'access-control-allow-methods': 'POST',
'access-control-allow-headers': 'Authorization, Content-Type, On-behalf-of, x-sg-elas-acl',
'access-control-max-age': '600',
'x-no-cors-reason': 'https://sendgrid.com/docs/Classroom/Basics/API/cors.html'
},
body: { errors: [Array] }
}
}

I am using the correct, API key suggested in the documentation and from: "an authorized email".

@jp-bitcube

Can you please use our error handling guide to capture the full error output and post it in a follow-up comment?

@eshanholtz I will set this up today and re-create the scenario. I know using purely the admin user email in the SendGrid account resolves the issues. Using a user allowed to access the account sometimes fails to send the mail.

I'm also experiencing this issue:

in package.json:

"@sendgrid/mail": "7.4.2",
"serverless": "2.23.0",

Using serverless framework to deploy the lambda. When invoking from local environment it seems to work just fine, but from a deployed lambda in AWS, no mail is sent and no error is caught:

Code to send:

const mailer = {
  send: async (mail: Mail) => {
    try {
      logger.info('Sending email', { to: mail.to });
      const resp = await sgMail.send(mail);

      for (const clientResponse of resp) {
        logger.info(clientResponse);
      }
    } catch (err) {
      logger.error(err);
      throw err;
    }
  },
};

The client responses are not being logged 鈽濓笍 either and the lambda finishes execution successfully 馃槺
Also note: the same code is being used by an application deployed to Heroku and it works just fine.

Apologies if this was just repeating the previous posts, let me know if you any more info would be helpful.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

danielflippance picture danielflippance  路  4Comments

Loriot-n picture Loriot-n  路  4Comments

murphman300 picture murphman300  路  4Comments

agostonbonomi picture agostonbonomi  路  3Comments

prasoonjalan picture prasoonjalan  路  3Comments