Converting Java Exceptions to HTTP Responses

When building serverless applications on AWS using Java and Spring Cloud Function, managing exceptions and returning meaningful HTTP responses to AWS API Gateway is crucial. The ApiGatewayResponseDecorator in the lambda-utilities library simplifies this process for your Java based lambdas. The decorator converts exceptions into a valid AWS API Gateway HTTP event response, preserving HTTP status codes.

See our code in oss-maven-standards on GitHub.

AWS Deployment Diagram

The decorator ensures that your Lambda functions remain clean of boilerplate HTTP response mapping, allowing you to focus on business logic while maintaining a consistent error handling contract with API Gateway.

graph TD
    Client[Client/Browser] -->|HTTPS| API[AWS API Gateway]
    API -->|Proxy| Lambda[AWS Lambda Function]
    subgraph Lambda Execution
        Decorator[ApiGatewayResponseDecorator]
        Function[Your Business Logic]
        Mapper[ApiGatewayExceptionMapper]
    end
    Lambda --> Decorator
    Decorator -->|Call| Function
    Function -.->|Throws Exception| Decorator
    Decorator -->|Maps| Mapper

How it works

The ApiGatewayResponseDecorator acts as a function wrapper that handles the entire request/response lifecycle for AWS API Gateway events.

Sequence Diagram

sequenceDiagram
    participant Client
    participant APIGateway
    participant LambdaFunction
    participant Decorator
    participant ExceptionMapper

    Client->>APIGateway: Request
    APIGateway->>LambdaFunction: Invoke
    LambdaFunction->>Decorator: process
    Decorator->>Decorator: execute function
    alt Success
        Decorator-->>LambdaFunction: 200 OK
    else Failure
        Decorator->>ExceptionMapper: map(Exception)
        ExceptionMapper-->>Decorator: HttpStatus
        Decorator-->>LambdaFunction: HttpStatus + Error JSON
    end
    LambdaFunction-->>APIGateway: Response
    APIGateway-->>Client: Response

Exception Conversion Process

  1. Request Reception: The decorator intercepts the input (an APIGatewayV2HTTPEvent).
  2. Execution: It delegates the actual work to the next function in the pipeline.
  3. Exception Catching: If an exception occurs, the decorator catches it and uses an ApiGatewayExceptionMapper to determine the correct HTTP status code.
  4. Response Construction: It creates an APIGatewayV2HTTPResponse with the correct status code, a content-type header, and a JSON body containing error details.

Error Management Logic

The ApiGatewayExceptionMapper provides the logic for determining the HTTP status code from an exception:

  • @ResponseStatus: If the exception is annotated with @ResponseStatus, the decorator respects the provided code or value as the HTTP status code.
  • ConstraintViolationException: Automatically maps to 400 Bad Request.
  • AccessDeniedException: Automatically maps to 403 Forbidden.
  • Default: Any other exception defaults to 500 Internal Server Error.

Example

Full example in development-test/jar-lambda-poc in oss-maven-standards repo. These jars are available on Central for use with maven.

Include the following dependency for your spring-cloud function:

<dependency>
   <groupId>com.limemojito.oss.standards.aws</groupId>
   <artifactId>lambda-utilities</artifactId>
   <version>18.0.x</version>
 </dependency>

In your spring cloud function code, you can decorate your function using the decorator factory as below:

public Function<APIGatewayV2HTTPEvent, APIGatewayV2HTTPResponse> hello(ApiGatewayResponseDecoratorFactory decoratorFactory) {
        log.info("Initialized Decorator Function");
        return decoratorFactory.create((apiEvent) -> {
            log.info("Received {}", apiEvent);
            return "world";
        });
    }