I'm using AWS S3, API Gateway and Lambda function to resize my images on the fly. I keep having this error when the image doesn't exist:
Failed to load resource: the server responded with a status of 502 ()
It should return a 404 instead. Here the code in the lambda function:
S3.headObject({Bucket: BUCKET, Key: parameters.orignalImagePath}, function(err,data) {
if(err) {
console.log("[404] Image Not Found: " + parameters.orignalImagePath);
return callback(null, {
statusCode: '404',
body: '{ "message":"Image not found." }',
})
}
});
Here the logs from CloudWatch:
START
{"errorMessage":"The specified key does not exist.","errorType":"NoSuchKey"....}
[404] Image Not Found: Folder/image.png
END
Why i'm getting a 502 when my code return a 404. I checked the ApiGateway settings but couldn't find anything.
I found this: https://aws.amazon.com/premiumsupport/knowledge-center/malformed-502-api-gateway/
It might be because of the malformed response. I'm going to try with the updated response and the four fields.
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
UPDATE: It definitely helps to change the response with those 4 fields. However, the same request gets sometimes a 404 and sometimes a 502.
Related
I am using CDK to create API endpoints. I would like to set 'Access-Control-Allow-Origin' to allow all in the header responses. Here is what I have tried
api.addGatewayResponse('4xx-error-response', {
type: ResponseType.DEFAULT_4XX ,
statusCode: '400',
responseHeaders: {
'Access-Control-Allow-Origin': `*`
},
templates: {
'application/json': '{ "message": "Access denied", "statusCode": "403", "type": "$context.error.responseType" }'
}
});
When I try to deploy this, I get the following error
Resource handler returned message: "Invalid mapping expression specified: Validation Result: warnings : [], errors : [Invalid mapping expression specified: *]
Question: How do I add a gateway response like in the below screenshot using CDK
try this way:
const resource = api.addGatewayResource('MyResource', {params...});
resource.addCorsPreflight({
allowOrigins: api.Cors.ALL_ORIGINS // eqivalent to ['*']
allowCredentials: true, // optional for credentials
});
According to the AWS CORS docs You need to set more than one header, so I would just use the method that is doing that for me.
The CDK test directories are a good source of information, next to the official docs. You may find there some useful examples. Here the ApiGateway insides.
in response header instead of * for Access-Control-Allow-Origin you'll have to use '*'.
Like this:
api.addGatewayResponse('invalid-endpoint-error-response', {
type: ResponseType.MISSING_AUTHENTICATION_TOKEN,
statusCode: '500',
responseHeaders: {
'Access-Control-Allow-Origin': "'*'",
},
templates: {
'application/json': '{ "message": $context.error.messageString, "statusCode": "488", "type": "$context.error.responseType" }'
}
});
My Spring Cloud Function(v3.1.6) based AWS Lambda function (without Lambda proxy integration) returns a list of data via API Gateway in the following format:
{
"isBase64Encoded": false,
"headers": {
"id": "<some_id>",
"contentType": "application/json",
"timestamp": "1644307568294"
},
"body": "{\"resultList\":[{\"id\":\"1\",\"name\":\"item\",(...some other fields...)}]}",
"statusCode": 200
}
My problem here is I want to return response.body in a JSON (ofc I've also created a Model schema) :
{
"resultList": [
{
"id": "1", "name": "item ",(...some other fields...)
}
]
}
I've configured an application/json based Response Template Mapping to transform the response to the desired format:
$util.parseJson($input.json('$.body'))
which returned that I wanted (check the attached image):
But when I call it via Postman, I've got this:
{
"message": "Internal server error"
}
and in CloudWatch I can see this logs:
2022-02-08T08:56:00.688+01:00 (...) Endpoint response body before transformations: [Binary Data]
2022-02-08T08:56:00.694+01:00 (...) Execution failed due to configuration error: Unable to transform response
What can be the problem?
I am trying to point a domain to Github pages site.
I am very new to working with domains and AWS services so I am finding it difficult to troubleshoot issues.
I have created an AWS ApiGateway that points to a lambda function which I would like to use to serve the content from Github pages, but currently, it is giving me the error:
{"message":"Internal Server Error"}
so when trying to fix this issue, I found instructions to make it log additional debug information. (instructions found at: https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-troubleshooting-lambda.html)
this is telling me that my configuration for the lambda function is incorrect.
The response from the Lambda function doesn't match the format that API Gateway expects. Lambda body contains the wrong type for field "headers"
I don't know what is expected so I don't know what needs to be changed... my entire lambda function is configured as:
exports.handler = async (event, context, callback) => {
let domain = 'https://github-org-name.github.io/my-repo-with-gh-pages/';
return {
statusCode: '301',
statusDescription: 'Moved Permanently',
headers: {
'location': [{
key: 'Location',
value: domain,
}],
'cache-control': [{
key: 'Cache-Control',
value: "max-age=3600"
}]
},
}
};
I am completely new to using AWS services, so I don't know if anything else needs to be configured. any help is appreciated.
The values in your headers dict must be strings, e.g:
{
"cookies" : ["cookie1", "cookie2"],
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headername": "headervalue", ... },
"body": "Hello from Lambda!"
}
See the bottom of this page:
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
I have a lambda (LAMBDA_PROXY) function with API gateway which is implemented in Golang (go-chi router).
when I invoke lambda from postman or browser, it gives 502 Bad Gateway status. In CloudWatch, I found following error message
Error while generating proxy response: Status code not set on response: errorString null
You need to respond with the correct response when using the "Use Lambda as Proxy" checkbox. Check out this document.
This may be more appropriate
The error you are getting is because, when you're using the API Gateway + Lambda proxy integration, the return value from the lambda function must be in the following JSON format:
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
Since you are using Golang, you can edit the return value of your main.go function by adding the following snippet as follows :
return events.APIGatewayProxyResponse{
Body: string(body),
StatusCode: 200
}, nil
Hope this helps!
I have created aws apigateway lambda integration for my proxy server. When i am making get request to the gateway, the request is successfully going through. The lambda function also executes successfully and writes response in outputstream with statusCode as 200. But apigateway always returns 502.
Snippet of handleRequest():
BufferedReader reader = new BufferedReader(new
InputStreamReader(inputStream));
JSONObject event = (JSONObject) parser.parse(reader);
request = Input.builder().setEvent(event).build();
Response response = requestManager.handleRequest(request);
logger.log(String.format("Response [%s]", response.toString()));
JSONObject responseJson = new JSONObject();
responseJson.put("statusCode", response.getStatusCode());
responseJson.put("headers", response.getHeaders());
JSONObject jsonBody = (JSONObject) parser.parse(response.getBody());
responseJson.put("body", jsonBody);
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
logger.log("response recieved");
logger.log(String.format("responseJson [%s]", responseJson));
writer.write(responseJson.toJSONString());
writer.close();
logger.log(String.format("output stream [%s]", outputStream));
Am i missing anything ?
502 errors with Lambda usuaully indicate that you are using the Lambda proxy method and not generating the proper JSON response. Make sure your response adheres to the appropriate format.
If you are still having problems, please share a sample JSON generated by your Lambda function.
I had the same issue where all of my logs were saying the lambda executed successfully but API Gateway was still returning 502s on every request. Turns out I forgot to configure the response status codes in the API Gateway Console so it was throwing errors because the response was "incorrect" even with proper formatting. Just add in a status code 200, 400, 403, etc. to the route on your gateway and that might solve your problem.
Make sure you're hitting your callback with the response before calling context.succeed(event) or some other call to context.
This was my problem and putting my callback first fixed the persistent 502 res.
There are two versions of the response format. It might be that are posting a version 1 format response to an endpoint expecting version 2:
Lambda function response for format 1.0
With the 1.0 format version, Lambda integrations must return a response in the following format.
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headername": "headervalue", ... },
"multiValueHeaders": { "headername": ["headervalue", "headervalue2", ...], ... },
"body": "..."
}
Lambda function response for format 2.0
With the 2.0 format version, API Gateway can infer the response format for you. API Gateway makes the following assumptions if your Lambda function returns valid JSON and doesn't return a statusCode:
isBase64Encoded is false.
statusCode is 200.
content-type is application/json.
body is the function's response.
The following examples show the output of a Lambda function and API Gateway's interpretation.
Lambda function output
API Gateway interpretation
"Hello from Lambda!"
{ "isBase64Encoded": false, "statusCode": 200, "body": "Hello from Lambda!", "headers": { "content-type": "application/json" }}
{ "message": "Hello from Lambda!" }
{ "isBase64Encoded": false, "statusCode": 200, "body": "{ \"message\": \"Hello from Lambda!\" }", "headers": { "content-type": "application/json" }}
To customize the response, your Lambda function should return a response with the following format:
{
"cookies" : ["cookie1", "cookie2"],
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headername": "headervalue", ... },
"body": "Hello from Lambda!"
}