3
votes

I'm trying to handle an error in a Lambda function written in Go.
The Lambda is triggered by API Gateway.
When I respond with a 200, I get the correct response.
But when I respond with a 500 code, I always receive {"message": "Internal server error"}

Here is part of the code:

func newErrReponse(message string) (events.APIGatewayProxyResponse, error) {
    return events.APIGatewayProxyResponse{
        Body:       message,
        StatusCode: 500,
    }, errors.New(message)
}

func handleRequest(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    return newErrReponse("some error")
}

func main() {
    lambda.Start(handleRequest)
}

I was expecting "some error", but I always get the internal server error. I tried JSON in the body but that didn't help. The integration request is of type LAMBDA_PROXY. That was the default.

How can I control the error response?

1
Unfamiliar with Go, but consider the difference between "successfully returning an error response" and "throwing an exception," errors.New(message) seems likely to be the issue -- your function didn't fail, it succeeded. You only want to return an error response for API Gateway to deliver back to the client, not indicate that an exception has occurred. Note the way it's done in Node: callback(null, {"statusCode": 400, "body": "Missing parameters of ..."}), where null is the (non-)"error." docs.aws.amazon.com/apigateway/latest/developerguide/… - Michael - sqlbot
Thanks. That was the problem. I also did a log.Fatal. It was a combination of 2 stupid errors :-) - roeland
Perfect. You're more familiar with this language than I am, so please feel free to write that up as an answer for the benefit of future visitors. - Michael - sqlbot
That's about errors that don't reach lambda? "If API Gateway fails to process an incoming request, it returns to the client an error response without forwarding the request to the integration backend" - roeland

1 Answers

5
votes

The lambda handler can return 2 values. interface{} and error:
https://godoc.org/github.com/aws/aws-lambda-go/lambda

Because I use API Gateway, The interface is of type APIGatewayProxyResponse:
https://godoc.org/github.com/aws/aws-lambda-go/events#APIGatewayProxyResponse

If the Lambda succeeds, the API Gateway will return the values from APIGatewayProxyResponse.

But if the Lambda don't succeeds, then you will get an internal server error.

If you return an error other then nil, then the Lambda failed.

When there is a panic() or os.Exit() then the Lambda also failed. This means a log.Fatal also fails a Lambda.

Here is more information about errors:
https://docs.aws.amazon.com/lambda/latest/dg/go-programming-model-errors.html

Lambda logs a panic (and other output) in CloudWatch