Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Lambda Error : 'Could not parse request body into json ' when url parameter contains JSON array

I am trying to invoke my Lambda function by passing parameters as below. it contains apostrophe(').

https://invoke_url?param=[["kurlo jack's book","Adventure Books",8.8,1]]

Stringifyed to be 'https://invoke_url?param=%5B%5B%229780786706211%22s....`

I used the mapping below to pass parameter to lambda

  "query": {
    #foreach($queryParam in $input.params().querystring.keySet())
    "$queryParam": "$util.escapeJavaScript($input.params().querystring.get($queryParam))" #if($foreach.hasNext),#end

    #end
  }  

I got following error

{"message": "Could not parse request body into json: Unrecognized character escape \'\'\' (code 39)\n at [Source: [B@5b70c341; line: 29, column: 65]"}  

i have also tried after removing double quotes from mapping template. But did't work.

like image 702
ARUNBALAN NV Avatar asked Sep 02 '16 11:09

ARUNBALAN NV


People also ask

Could not parse request body into JSON could not parse payload into JSON AWS Lambda?

The "InvalidRequestContentException - Could not Parse Request body into JSON Error" error occurs when invoking a lambda function with syntactically incorrect JSON payload, or forgetting to set the --cli-binary-format parameter to raw-in-base64-out . Copied! The reason is the dangling comma in the --payload parameter.

What happens when AWS Lambda throws exception?

If Lambda encounters an error, it returns an exception type, message, and HTTP status code that indicates the cause of the error. The client or service that invoked the Lambda function can handle the error programmatically, or pass it along to an end user.

How do you make lambda fail?

Lambda functions can fail in three cases: An unhandled exception is raised — whether if we received an invalid input, an external API failed, or just a programming bug occurred. Timeout — Lambda running longer than the configured timeout duration is violently closed with a 'Task timed out after … seconds' message.


2 Answers

Be sure to add .replaceAll("\\'","'") to your request body passthrough template after .escapeJavaScript(data)

I found this bit from AWS's documentation to be very helpful for this issue:

$util.escapeJavaScript()

Escapes the characters in a string using JavaScript string rules.

Note This function will turn any regular single quotes (') into escaped ones (\'). However, the escaped single quotes are not valid in JSON. Thus, when the output from this function is used in a JSON property, you must turn any escaped single quotes (\') back to regular single quotes ('). This is shown in the following example: $util.escapeJavaScript(data).replaceAll("\\'","'")

like image 190
Beau Herndon Avatar answered Oct 20 '22 15:10

Beau Herndon


I don't have a solution but I have narrowed the root cause. Lambda does not seem to like single quotes to be escaped with a single slash.

If you hardcode your mapping template to look like this:

{
    "query-fixed": {
        "param": "[[\"kurlo jack\\'s book\",\"Adventure Books\",8.8,1]]"
    }
}

my test Lambda invocation succeeds. However, if you hardcode the template to this:

{
    "query-fixed": {
        "param": "[[\"kurlo jack\'s book\",\"Adventure Books\",8.8,1]]"
    }
}

I get the same error message that you got above. Unfortunately, the second variation is what API Gateway produces for the Lambda invocation.

A workaround might involve using the template to replace single quotes escaped with slash to two slashes. See Replace a Substring of a String in Velocity Template Language

I'll follow up with Lambda internally and update if I hear anything or have a functional workaround.

like image 23
Lorenzo de Lara Avatar answered Oct 20 '22 16:10

Lorenzo de Lara