EJSON error with coffeescript and SendGrid

I am integrating SendGrid. If I leave the code as embedded JS, everything is fine. Once I modify it to be coffeescript, I get an error. I think it’s an issue with the msg data when I call sgMail.send(msg).

My server code is here:

  sendEmail: (to) ->
    sgMail = require('@sendgrid/mail')
    sgMail.setApiKey(process.env.SENDGRID_API_KEY)
    msg =
      to: to
      from: 'test@example.com'
      subject: 'Sending with SendGrid is Funny'
      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)

Error is here:

W20190305-07:41:02.571(-8)? (STDERR) (node:83322) UnhandledPromiseRejectionWarning: RangeError: Maximum call stack size exceeded
W20190305-07:41:02.572(-8)? (STDERR)     at Array.map (<anonymous>)
W20190305-07:41:02.572(-8)? (STDERR)     at Object.EJSON.clone.v [as clone] (packages/ejson/ejson.js:575:14)
W20190305-07:41:02.572(-8)? (STDERR)     at Object.keys.forEach.key (packages/ejson/ejson.js:595:22)
W20190305-07:41:02.572(-8)? (STDERR)     at Array.forEach (<anonymous>)
W20190305-07:41:02.572(-8)? (STDERR)     at Object.EJSON.clone.v [as clone] (packages/ejson/ejson.js:594:18)
W20190305-07:41:02.572(-8)? (STDERR)     at Object.keys.forEach.key (packages/ejson/ejson.js:595:22)
W20190305-07:41:02.572(-8)? (STDERR)     at Array.forEach (<anonymous>)
W20190305-07:41:02.572(-8)? (STDERR)     at Object.EJSON.clone.v [as clone] (packages/ejson/ejson.js:594:18)
W20190305-07:41:02.573(-8)? (STDERR)     at Object.keys.forEach.key (packages/ejson/ejson.js:595:22)
W20190305-07:41:02.573(-8)? (STDERR)     at Array.forEach (<anonymous>)
W20190305-07:41:02.573(-8)? (STDERR)     at Object.EJSON.clone.v [as clone] (packages/ejson/ejson.js:594:18)
W20190305-07:41:02.573(-8)? (STDERR)     at Object.keys.forEach.key (packages/ejson/ejson.js:595:22)
W20190305-07:41:02.573(-8)? (STDERR)     at Array.forEach (<anonymous>)
W20190305-07:41:02.573(-8)? (STDERR)     at Object.EJSON.clone.v [as clone] (packages/ejson/ejson.js:594:18)
W20190305-07:41:02.573(-8)? (STDERR)     at Object.keys.forEach.key (packages/ejson/ejson.js:595:22)
W20190305-07:41:02.573(-8)? (STDERR)     at Array.forEach (<anonymous>)
W20190305-07:41:02.574(-8)? (STDERR) (node:83322) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
W20190305-07:41:02.574(-8)? (STDERR) (node:83322) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

what’s in to? can you log the content of to ?

ah and show us the client code that calls this method/function

it’s just an email "test@example.com".

BTW - I think that it has to do with ending the meteor method call on the sgMail.send(msg) since if I add a console.log statement as the last line, everything works ok.

I don’t use CS, so feel free to ignore me, but perhaps it’s not transpiling the code correctly. Can you see what’s been generated?

That error (Maximum call stack size exceeded) looks like an infinite loop on the stack (like a runaway recursion, for example).

the calls tacks says EJSON, if i remember correctly, this might happen if you send non serializeble objects through meteor methods, but i am not sure.

2 Likes

YES! You’re correct. If the object contains functions, for example, or is the this object.

Perhaps CS is automatically providing a return something.

Resolution: explicitly return null or something else that’s sensible.

1 Like

Yep! If I add a final line of console.log("message sent") then all is well.

Very odd.

coffescript is sometimes a bit dangerous because the last line is always the return value of a function. So whatever sgMail.send(msg) is returning, will get sent to the client via serialisation.

I advice to always think about what to return on a method and return that explicitly. e.g. just return true here or so

1 Like

Ah. I didn’t realize that. I added ‘true’ as the last line. Solved the problem as well.

I’ve never come across that concept though. What is ‘true’ telling the client?

Nothing, unless you choose to use it on the client. You could return almost anything. You’re just working round a nuance of CS.

you can send data to the client. Now you are simply telling “true” to the client. you could als return null or undefined or anything you want. The only exception is object with functions in it or anything that is not serializable :wink:

1 Like