Lambda handler functions
Overview
Backend logic is done by Lambda functions, Lambda functions can be triggered from multiple services, we split our code into two parts, a handler function which is the initial entry point into the Lamdba, it receives the request and performs request method specific handling, it then invokes the main logic of the Lambda, which is request method agnostic, allowing it to be invoked by any request method.
CorrelationId and Logger instances
Our middleware has CorrelationId and Logger classes which manage the passing of correlation ids between services and output these ids to logs. If the request method invokes the lambda with a single workflow/message these are placed into global instances, but if the request service handles batches of messages each message will carry its own instance.
In order for our main logic to be able to handle single or batch requests we cannot assume the global instances are to be used, to allow for this we standardize that main logic always receives correlationIds and logger parameters when invoked, the handler function sets which are used. Because these will always be present standardize them as the first two parameters.
error handling
Errors will be handled differently depending on the requesting resource type. There are three main errors we plan for:
- No retry: Detected in main logic, do not need to retry, eg input from client invalid
- Temporary error: Detected in main logic, want to retry, eg an external service is not responding
- Unhandled error: Happens prior to main logic
Different handlers will handle these differently, eg SQS handlers which can process batches need to handle return values per Message recieved. Because our main logic is request method agnostic logic we return errors in a way that the handler can process how it needs to.
No retry errors we return as an error object, the handler can test the return values type to see whether a no retry error occured.
Temporary errors we throw from the main logic, the handler catches this and arranges retries if applicable.
Unhandled errors might happen when a serious mis-formating of the request occurs or a core library fails, this will likely happen before invoking the main logic and might simply be thrown from the Lambda handler function.
Handlers
Api Gateway
error handling
All 3 error types will be passed back to the client as a failed request, it is up to the client to attempt retries
return value
Return the same value the main function returns, but wrapped in a success html/rest response.
SQS
Designed to manage batches of message.
error handling
No retry errors simply return as normal, as there is no client to recieve a notification of the error and no need to retry.
Temporary errors we want to retry, we manage our own SQS retry logic which gives us more power over the retry behaviour, but we must be careful to detect multiple reties and deliver to DLQ to prevent infinite loops.
Unhandled errors we manage using the AWS Lambda SQS trigger settings, this will have a retry count setting and a DLQ configured. We need to use the AWS managed service as we cannot guarantee our logic will catch and handle the error (eg if it happens inside middleware), it could be a temporary error so a couple of retries is acceptable, but these are an edge case and should not happen in normal operation.
return value
There is no client to receive return values.