Lambda#Edge function result failed validation - aws-lambda

I have a lambda#edge in Viewer Request that is generating this error:
ERROR Validation error: Lambda function result failed validation, the function tried to add read-only header, headerName : Transfer-Enoding.
I tried to return this event in case of redirection:
const response = {
status: '301',
statusDescription: 'Found',
headers: {
'location': [{
key: 'location',
value: 'https://test.com'
}]
}
}
callback(null, response)
I also tried keeping the same event but I get the same error
const response = event.Records[0].cf.response;
response.status = 301;
response.statusDescription = 'Found';
response.headers['location'] = [{ key: 'Location', value:'https://www.test.com'}];
Cqn someone tells me how to fix this ?
PS: Even requests that pass by this lambda and doesnt verify the redirection condition result in this error also.

Related

Fitbit URL callback giving a response of NULL

I'm having trouble getting a response from a callback uri and I would really appreciate any help you could give me.
I am trying to use the Fitbit API which requires you to use a callback url to get an Auth Code.
Workflow:
1. Go to Fitbit url to get user to allow the app access to their personal data.
2. User agrees to the conditions
3. User gets redirected to my API
4. The API returns the code from (Code is located in URL and I can access it)
5. I console.log the code out to verify it
6. API returns the code
7. I work with code then exchanging it for an access token.
The problem is that I don't return the code (Or anything )when I return to the app even though I can console.log it on the API. The response I get is NULL
Here is the URL:
url = "https://www.fitbit.com/oauth2/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=https://REDIRECT_URL&scope=activity%20heartrate%20location%20nutrition%20profile%20settings%20sleep%20social%20weight&expires_in=604800";
I then open the URL in the InAPPBrowser successfully:
if (url !== "") {
const canOpen = await Linking.canOpenURL(url)
if (canOpen) {
try {
const isAvailable = await InAppBrowser.isAvailable()
if (isAvailable) {
const result =InAppBrowser.open(url, {
// iOS Properties
dismissButtonStyle: 'done',
preferredBarTintColor: 'gray',
preferredControlTintColor: 'white',
// Android Properties
showTitle: true,
toolbarColor: '#6200EE',
secondaryToolbarColor: 'black',
enableDefaultShare: true,
}).then((result) => {
console.log("Response:",JSON.stringify(result))
Linking.getInitialURL().then(url => {
console.log("Tests: ",url)
this._setTracker(url as string);
});
})
} else Linking.openURL(url)
} catch (error) {
console.log("Error: ",error)
}
}
}
From here the URL opens successfully.
Here is the API now which is done in Typescript on AWS serverless and Lambda
export const handler: APIGatewayProxyHandler = async (event, _context, callback) =>{
let provider = event.path
//prints code
let x = event.queryStringParameters
console.log("Code: ",x)
const response = {
statusCode: 200,
body: "Success"
};
return response;
}
Please let me know if further detail is required?
Thank you!
Right so it turns out what I was doing was correct apart from the response should have been 301 which is a redirect response.
const response= {
statusCode: 301,
headers: {
"location": `app://CALLBACK RESPONSE ADDRESS?type=${provider}`
},
body: "Boom"
}

NodeJS: AWS SDK V3: Not receiving any response data from lambda function

I'm trying to use the v3 javascript sdk to invoke a AWS Lambda function, and I'm having problems getting any meaningful response.
My code looks like so...
const { Lambda } = require("#aws-sdk/client-lambda");
const client = new Lambda();
const params = {
FunctionName: "MyLamdaFuncton",
Payload: JSON.stringify({ "action": "do_something" }),
InvocationType: "Event"
};
client.invoke(params)
.then((response) => {
console.log(JSON.stringify(response,null,4));
})
.catch((err) => {
console.error(err);
})
I can confirm from checking the CloudWatch logs that the lambda function works as exepcted. However this is the response I get in my NodeJS code...
{
"$metadata": {
"httpStatusCode": 202,
"requestId": "d6ba189d-9156-4f01-bd51-efe34a66fe34",
"attempts": 1,
"totalRetryDelay": 0
},
"Payload": {}
}
How do I get the actual response and status from the Lambda function?
If I change the payload above to intentionally throw an exception in my Lambda, the response in the console is still exactly the same.
update:
The Lambda function is written in Ruby. The response is returned like so...
{ statusCode: 200, body: JSON.generate(response.success?) }
where "response" is from another service it calls internally.
I've figured out what I was doing wrong. The issue was the "InvocationType". I got it working by changing to...
InvocationType: "RequestResponse"
Then I had to extract the response data like so...
const response_data = JSON.parse(new TextDecoder("utf-8").decode(response.Payload))

AWS lambda api gateway error “Malformed Lambda proxy response”

My AWS ApiGateway invokes this lambda function :
const handler = (event, context) => {
const theResponse = {
"statusCode": 200,
"isBase64Encoded": false,
"headers": {
"Content-Type": "application/json"
},
"body": "hello, world"
};
switch (event.httpMethod) {
case 'GET':
theResponse["body"] = `method ${event.httpMethod} detected`;
break;
default:
theResponse["statusCode"] = 404;
theResponse["body"] = `Unsupported method ${event.httpMethod} detected`;
break;
}
return theResponse;
};
module.exports = {
handler,
};
Any thoughts to why this errors with :
{"message": "Internal server error"}
Received response. Status: 200, Integration latency: 344 ms
Endpoint response body before transformations: null
Execution failed due to configuration error: Malformed Lambda proxy response
Method completed with status: 502
I tried replacing return (theResponse); with return JSON.stringify(theResponse); but this also returns the same error.
However if I replace return theResponse; with return {"statusCode":200, "body":"hello, world"}; then the API executes without errors.
Looks to me like a lamda_proxy integration issue but I can't see why. thanks.
Bearrider!
I guess it is related to the way you are building your response object:
Try stringify only the body attribute:
case 'GET':
theResponse["body"] = JSON.stringify(`method ${event.httpMethod} detected`);
break;
default:
theResponse["statusCode"] = 404;
theResponse["body"] = JSON.stringify(`Unsupported method ${event.httpMethod} detected`);
break;
}

Unhandled Rejection (TypeError): Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body

Unhandled Rejection (TypeError): Failed to execute 'fetch' on
'Window': Request with GET/HEAD method cannot have body.
Getting the above error.
export const checkMobile = mobile => {
return ajax(`/mobiles/search`, { method: "GET", body: mobile });
};
function ajax(uri, options = {}) {
const defaultOptions = getDefaultOptions();
options.method = options.method ? options.method : defaultOptions.method;
if (!options.formType) {
options.headers = options.headers
? options.headers
: defaultOptions.headers;
}
options.credentials = options.credentials
? options.credentials
: defaultOptions.credentials;
if (options.body && !options.formType) {
options.body = buildParam(options.body);
}
uri = uri.startsWith("/") ? uri : "/" + uri;
console.log(`${CLIENT_URL}${uri}`);
return fetch(`${CLIENT_URL}${uri}`, options).then(data => data.json());
}
Why I have not been allowed to add body data. Now how will I pass the data to the back end. I am using react in front end.
Check your options object and ensure body is undefined if you're using GET.
GET requests should not be posting any data in the body. If you plan on sending data, you probably want to use POST as the method.

Django returning status code 400 with error message from view

I have a view that receives a form submit request via ajax. Sometimes it returns bad request based on certain criteria or in case an exception is raised. Now, sending back simple HttpResponse(status=400) is plain simple. Can I send a reason along with it a reason that I can access using xhr.responseText?
If I understand you right, you can return 400 with some context:
context = {
'reason': 'your reason'
}
response = render(request, '400.html', context)
response.status_code = 400
return response
and for cases with ajax, you just return HttpResponse:
context = {
'status': '400', 'reason': 'you can access this view only via ajax'
}
response = HttpResponse(json.dumps(context), content_type='application/json')
response.status_code = 400
return response
and in your js code:
$.ajax({
// ...
// ...
}).fail(function(data){
var status = data.status;
var reason = data.reason;
});

Resources