Skip to content

Non-object events are not handled #232

Closed
@grahamrp

Description

@grahamrp

Expected Behavior

When a lambda is invoked with an event that is not an object (e.g. an array or value type) the instrumentation should handle this case and continue to function as normal.

Actual Behavior

Datadog wrapper fails with TypeError: argument of type 'NoneType' is not iterable (when "null" is sent as the Payload) or TypeError: argument of type 'int' is not iterable (when an integer is sent as the Payload). No logs are sent to Datadog.

Steps to Reproduce the Problem

  1. Using boto3 create a new lambda_client with credentials
  2. lambda_client.invoke(FunctionName="foo", InvocationType="RequestResponse", Payload=json.dumps(1)) or json.dumps(None), or any other non-object json.
  3. Review the CloudWatch logs
  4. Observe no logs being sent to Datadog

Specifications

  • Datadog Lambda Layer version: 23
  • Python version: 3.9

Stacktrace

# CloudWatch Logs from lambda_client.invoke(FunctionName="foo", InvocationType="RequestResponse", Payload=json.dumps(None)
START RequestId: 3897a891-f42d-427d-860b-b9b5ae9e0959 Version: $LATEST
--
LOGS	Name: datadog-agent	State: Subscribed	Types: [platform,function,extension]
EXTENSION	Name: datadog-agent	State: Ready	Events: [INVOKE,SHUTDOWN]
Traceback (most recent call last):
File "/var/lang/lib/python3.9/site-packages/datadog_lambda/wrapper.py", line 159, in _before
dd_context, trace_context_source = extract_dd_trace_context(
File "/var/lang/lib/python3.9/site-packages/datadog_lambda/tracing.py", line 335, in extract_dd_trace_context
elif "headers" in event:
TypeError: argument of type 'NoneType' is not iterable
END RequestId: 3897a891-f42d-427d-860b-b9b5ae9e0959
REPORT RequestId: 3897a891-f42d-427d-860b-b9b5ae9e0959	Duration: 7675.97 ms	Billed Duration: 8237 ms	Memory Size: 512 MB	Max Memory Used: 101 MB	Init Duration: 560.23 ms	XRAY TraceId: 1-62b96915-4c10201259b4b43b7ccfa27b	SegmentId: 517ac22b2d33298c	Sampled: true

The reason I think this is a bug is that the AWS Lambda documentation mentions support for non-object payloads:

The first argument is the event object. An event is a JSON-formatted document that contains data for a Lambda function to process. The Lambda runtime converts the event to an object and passes it to your function code. It is usually of the Python dict type. It can also be list, str, int, float, or the NoneType type.

I think what is happening is extract_dd_trace_context is assuming a deserialised json object at tracing.py#L335 elif "headers" in event:.

When the event is not a deserialised object (i.e. not a dict) the in operator will either fail, or result in strange behaviour, for example in a case where a string or array sent in the payload happens to contain the sequence headers.

I think issue #225 stems from a similar situation.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions