Sendgrid-nodejs: Substitutions must be strings, else 400 Bad Request when sending

Created on 31 Aug 2016  ·  13Comments  ·  Source: sendgrid/sendgrid-nodejs

Issue Summary

Trying to send an email using a template + substitutions that include an integer gives a 400 Bad Request error with no explanation.

Steps to Reproduce

  1. Create a template with a substitution (eg %test%)
  2. Attempt to send that template using sendgrid-node where the substitution is an integer

_Expected_ - Email is sent, or error with info about the problem.

_Actual_ - 400 Bad Request with no details as to the problem.

SENDMAIL ERROR { statusCode: 400,
  body: '{"errors":[{"message":"Bad Request","field":null,"help":null}]}',
  headers:
   { server: 'nginx',
     date: 'Wed, 31 Aug 2016 14:32:57 GMT',
     'content-type': 'application/json',
     'content-length': '63',
     connection: 'close',
     'x-frame-options': 'DENY' } }

Here is a code example:

var mail = new helper.Mail()
mail.setFrom( new helper.Email( '[email protected]' ) )
mail.setTemplateId( "THE_TEMPLATE_ID" )

var personalization = new helper.Personalization()
personalization.addTo( new helper.Email( '[email protected]' ) )
var sub = new helper.Substitution( `%test%`, 42 )
personalization.addSubstitution( sub )
mail.addPersonalization( personalization )

sgClient.API( sgClient.emptyRequest( {
  method: 'POST',
  path: '/v3/mail/send',
  body: mail.toJSON()
} ) ).catch( function( err ) {
  console.error( 'SENDGRID ERROR', err.response )
} )

The exact same code except with '42' instead of 42 for the substitution works.

While it would be super great if SendGrid itself would not error like this (or would explain the problem in the error message, like which field and that it wasn't accepted because it's a number), I think sendgrid-node could/should easily handle it by just toString()-ing substitutions.

Happy to submit a PR, but when I went to go and write a failing test there are no docs on how to run the tests, and in the tests I saw a lot of stuff about test hosts that I wouldn't have running.

Technical details:

  • sendgrid-nodejs Version: 2.2.1
  • Node.js Version: 4.1.0
hacktoberfest help wanted community enhancement

Most helpful comment

@wizysanjay call toString on your substitutions before passing to the library. For example instead of:

personalization.addSubstitution( new helper.Substitution( `%number%`, number ) )

Do this:

personalization.addSubstitution( new helper.Substitution( `%number%`, number.toString() ) )

All 13 comments

Hi @rfunduk,

Thanks for the detailed feedback!

This is a known issue and the API team has a fix on their backlog to provide an appropriate error string.

You are correct, we need this fixed in the library and we would love your pull request.

I ma happy to walk you through how the tests work. But first, we will need a signed CLA: https://github.com/sendgrid/sendgrid-nodejs/blob/master/CONTRIBUTING.md

Thanks!

I got the same problem. How do I fix this

Thanks

@wizysanjay call toString on your substitutions before passing to the library. For example instead of:

personalization.addSubstitution( new helper.Substitution( `%number%`, number ) )

Do this:

personalization.addSubstitution( new helper.Substitution( `%number%`, number.toString() ) )

+1

I got it. Thanks

I can't believe I spent an afternoon debugging before I came across this. A substitution must be string mention in the docs at least would be nice…which I'd add myself, but at this point I can't even find where that would go in the docs.

Hi @dangerismycat,

:( not cool. This is documented here, but that's not helpful for your use case.

We are going to build this into the library so you don't even need to worry about it. Your vote has been added to help increase the priority.

Awesome, glad it's upped the priority. If it's a simple fix and you can point me in the right direction (repo or file), I can take care of it.

@dangerismycat,

Awesome! The fix would likely go here.

@thinkingserious Hm…looks like the build failed. Are there associated tests I need to update, or anything else?

Something has been amiss with Travis CI builds for those not in the SendGrid organization. I'm not quite sure what is going on, but I will verify locally.

Hey, still getting this issue on "@sendgrid/client": "^6.2.1".
Sending this while sub is an integer doesn't work and gives

body: {
  personalizations: [{
    to: [{
      email: userEmail
    }],
    subject: `blah blah blah`,
    substitutions: {
      '{{sub}}': sub
    }
  }],
  from: {
    email: '[email protected]',
    name: 'blah blah'
  },
  template_id
}
err { Error: Bad Request
    at Request.http [as _callback] (node_modules/@sendgrid/client/src/classes/client.js:124:25)
    at Request.self.callback (node_modules/request/request.js:186:22)
    at emitTwo (events.js:126:13)
    at Request.emit (events.js:214:7)
    at Request.<anonymous> (node_modules/request/request.js:1163:10)
    at emitOne (events.js:116:13)
    at Request.emit (events.js:211:7)
    at IncomingMessage.<anonymous> (node_modules/request/request.js:1085:12)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:111:20)
    at IncomingMessage.emit (events.js:208:7)
    at endReadableNT (_stream_readable.js:1055:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)
  code: 400,
  message: 'Bad Request',
  response: 
   { headers: 
      { server: 'nginx',
        date: 'Fri, 20 Apr 2018 16:17:42 GMT',
        'content-type': 'application/json',
        'content-length': '63',
        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] } } }
where the errors: array is [ { message: 'Bad Request', field: null, help: null } ]

However, when I change sub in the request to ${sub}, it'll work

Regards

Hello @Mauyeung,

Would you mind opening a new issue? Thanks!

It looks like this may be a bug, as I see that we are supposed to convert that to a string for you under the hood.

With Best Regards,

Elmer

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ifndefdeadmau5 picture ifndefdeadmau5  ·  33Comments

AAverin picture AAverin  ·  39Comments

sydneyhenrard picture sydneyhenrard  ·  17Comments

machinshin picture machinshin  ·  35Comments

mckravchyk picture mckravchyk  ·  20Comments