Home > Software engineering >  AWS Lambda - Error Parsing Event Body String to JSON -
AWS Lambda - Error Parsing Event Body String to JSON -

Time:08-06

I am trying to set up a function as a webhook handler. I am receiving an error when trying to convert the Lambda Event Body into a dictionary that I can access data from.

If it's relevant, I just gave the Lambda funciton its own URL when creating it instead of using API Gateway as a trigger. This seemed to be functioning fine with my test events, but not when I started getting events from the application that is actually sending the webhooks.

Here is what the Lambda event looks like when I print(json.dumps(event)). Some data removed for privacy.

{
    "version": "2.0",
    "routeKey": "$default",
    "rawPath": "/",
    "rawQueryString": "",
    "headers": {
        "content-type": "application/json",
    },
    "requestContext": {
        "routeKey": "$default",
        "stage": "$default",
        "time": "04/Aug/2022:17:16:05  0000",
        "timeEpoch": 1659633365645
    },
    "body": "{\n    \"siteId\": 123,\n    \"clientId\": \"100000009\",\n    \"clientUniqueId\": 100000009,\n    \"creationDateTime\": \"2018-08-28T06:45:58Z\",\n    \"status\": \"Non-Member\",\n    \"firstName\": \"John\",\n    \"lastName\": \"Smith\",\n    \"email\": \"[email protected]\",\n    \"mobilePhone\": \"8055551234\",\n    \"homePhone\": null,\n    \"workPhone\": null,\n    \"addressLine1\": \"123 ABC Ct\",\n    \"addressLine2\": ,\n    \"city\": \"San Luis Obispo\",\n    \"state\": \"CA\",\n    \"postalCode\": \"93401\",\n    \"country\": \"US\",\n    \"birthDateTime\": \"1989-07-02T00:00:00Z\",\n    \"gender\": \"Male\",\n    \"appointmentGenderPreference\": null,\n    \"firstAppointmentDateTime\": \"2018-08-29T06:45:58Z\",\n    \"referredBy\": null,\n    \"isProspect\": false,\n    \"isCompany\": false,\n    \"isLiabilityReleased\": true,\n    \"liabilityAgreementDateTime\": \"2018-08-29T06:45:58Z\",\n    \"homeLocation\": 1,\n    \"clientNumberOfVisitsAtSite\": 2,\n    \"indexes\": [\n        {\n            \"indexName\": \"LongtermGoal\",\n            \"indexValue\": \"IncreasedFlexibility\"\n        }\n    ],\n    \"sendPromotionalEmails\": true,\n    \"sendScheduleEmails\": true,\n    \"sendAccountEmails\": true,\n    \"sendPromotionalTexts\": false,\n    \"sendScheduleTexts\": false,\n    \"sendAccountTexts\": false,\n    \"creditCardLastFour\": \"1445\",\n    \"creditCardExpDate\": \"2025-06-30T00:00:00Z\",\n    \"directDebitLastFour\": \"7754\",\n    \"notes\": \"Notes about the client.\",\n    \"photoUrl\": \"https://clients.mindbodyonline.com/studios/ACMEYoga/clients/100000009_large.jpg?osv=637136734414821811\",\n    \"previousEmail\": null\n}",
    "isBase64Encoded": false
}

Obviously, the type() of the body is a string, but it errors when trying to convert to a Dict with json.loads().

I suspect this has to do with the whitespace and escaped newline characters, but I got stuck when trying to deal with that.

Here is my code....

import json
import requests
import datetime


def lambda_handler(event, context):

    eventData = json.loads(event["body"])

    today = datetime.date.today()

    headers = {
        "Api-Token": "",
        "Accept": "application/json",
        "Content-Type": "application/json"
    }

    data = {
        "contact": {
            "email": eventData.get("email"),
            "firstName": eventData.get("firstName"),
            "lastName": eventData.get("lastName"),
            "phone": eventData.get("mobilePhone"),
            "fieldValues": [{
                "field": "15",
                "value": today.strftime("%Y-%m-%d")
                },
                {
                "field": 1,
                "value": eventData.get("clientId")
                }
            ]
        }
    }

    sync_contact = requests.post("[URL]", headers=headers, json=data)

    return {
        'statusCode': 200,
        'body': json.dumps(sync_contact.json()),
    }

The Error I receive is:

Expecting value: line 14 column 21 (char 379)
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 18, in lambda_handler
    eventData = json.loads(event['body'])
  File "/var/lang/lib/python3.9/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/var/lang/lib/python3.9/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/var/lang/lib/python3.9/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None

CodePudding user response:

This error is produced, as the traceback already tells you, that you pass a variable that is None, blankstring or other incompatible datatype into json.loads().

I tried it myself and I get this error:

    ...
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 14 column 21 (char 379)

char 379 is the emtpy char after \"addressLine2\":, means addressLine2's value is empty, which is not allowed.

  • Related