TLDR; If you are using an Open API spec, Add this to the root of your Open API spec:
x-amazon-apigateway-gateway-responses:
BAD_REQUEST_PARAMETERS:
statusCode: 400
responseTemplates: application/json: "{\n \"message\": \"Bad Request\", \n \"cause\": $context.error.validationErrorString \n }"
BAD_REQUEST_BODY:
statusCode: 400
responseTemplates: application/json: "{\n \"message\": \"Bad Request\", \n \"cause\": $context.error.validationErrorString \n }"
Explained:
If you are using an Open API spec (Yaml file), you can add some default error handlers of a predefined set of 'Gateway responses' to the root of your open API spec and configure them to return specific information by using the 'context' (a set of variables).
There is a limited set of Gateway responses, here is a list: https://docs.aws.amazon.com/apigateway/latest/developerguide/supported-gateway-response-types.html
And here is the variables available via the context: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#context-variables-template-example
Here is an example of what I return in an error:
{
"message": "Bad Request",
"cause": "Missing value ...",
"code": "LTAPI_400",
"X-Transaction-ID": "io7b3c78vtv87baxd324"
}
So my 'x-amazon-apigateway-gateway-responses' are:
x-amazon-apigateway-gateway-responses:
ACCESS_DENIED:
statusCode: 401
responseTemplates:
application/json: "{\n \"message\": \"$context.authorizer.context.error_type\", \n \"cause\": \"$context.authorizer.context.error_message\", \n \"code\": LTAPI_401, \n \"X-Transaction-ID\": \"$input.params('X-Transaction-ID')\" \n }"
AUTHORIZER_FAILURE:
statusCode: 503
responseTemplates:
application/json: "{\n \"message\": \"Service Unavailable\", \n \"cause\": \"The request couldn't be completed successfully because of an error in a downstream system.\", \n \"code\": LTAPI_503, \n \"X-Transaction-ID\": \"$input.params('X-Transaction-ID')\" \n }"
AUTHORIZER_CONFIGURATION_ERROR:
statusCode: 503
responseTemplates:
application/json: "{\n \"message\": \"Service Unavailable\", \n \"cause\": \"The request couldn't be completed successfully because of an error in a downstream system.\", \n \"code\": LTAPI_503, \n \"X-Transaction-ID\": \"$input.params('X-Transaction-ID')\" \n }"
BAD_REQUEST_PARAMETERS:
statusCode: 400
responseTemplates:
application/json: "{\n \"message\": \"Bad Request\", \n \"cause\": $context.error.validationErrorString, \n \"code\": LTAPI_400, \n \"X-Transaction-ID\": \"$input.params('X-Transaction-ID')\" \n }"
BAD_REQUEST_BODY:
statusCode: 400
responseTemplates:
application/json: "{\n \"message\": \"Bad Request\", \n \"cause\": $context.error.validationErrorString, \n \"code\": LTAPI_400, \n \"X-Transaction-ID\": \"$input.params('X-Transaction-ID')\" \n }"
DEFAULT_5XX:
statusCode: 500
responseTemplates:
application/json: "{\n \"message\": \"Internal Server Error\", \n \"cause\": \"An unexpected error has occurred.\", \n \"code\": LTAPI_500, \n \"X-Transaction-ID\": \"$input.params('X-Transaction-ID')\" \n }"