I'd like to have different http status codes but it looks like api gateway always returns a 200 status code even if the lambda function is returning an error.
// Return An Error Message String In Your Lambda Function
return context.fail('Bad Request: You submitted invalid input');
// Here is what a Lambda Error Regex should look like.
// Be sure to include the period and the asterisk so any text
// after your regex is mapped to that specific HTTP Status Code
Bad Request: .*
Your API Gateway route should return this:
HTTP Status Code: 400
JSON Error Response:
{
errorMessage: "Bad Request: You submitted invalid input"
}
I see no way to copy these settings and re-use it for different methods, so we have much annoying redundant manual inputting to do!
exports.handler = function(event, context) {
var response = {
status: 400,
errors: [
{
code: "123",
source: "/data/attributes/first-name",
message: "Value is too short",
detail: "First name must contain at least three characters."
},
{
code: "225",
source: "/data/attributes/password",
message: "Passwords must contain a letter, number, and punctuation character.",
detail: "The password provided is missing a punctuation character."
},
{
code: "226",
source: "/data/attributes/password",
message: "Password and password confirmation do not match."
}
]
}
context.fail(JSON.stringify(response));
};
Finally, you setup a Mapping Template to extract the JSON response from the errorMessage property returned by Lambda. The Mapping Template looks like this:
exports.handler = (event, context, callback) => {
// ..
var someError1 = {
error: {
httpStatusCode: 500,
details: [
{
code: "ProductNotFound",
message: "Product not found in Cart",
description: "Product should be present after checkout, but not found in Cart",
source: "/data/attributes/product"
},
{
code: "PasswordConfirmPasswordDoesntMatch",
message: "Password and password confirmation do not match.",
description: "Password and password confirmation must match for registration to succeed.",
source: "/data/attributes/password",
}
]
}
};
return callback(new Error(JSON.stringify(someError1)));
}
笔记
- I believe the methods on context such as context.succeed() are deprecated. They are no longer documented although they do still seem to work. I think coding to the callback API is the correct thing going forward.
module.exports.lambdaHandler = (event, context, done) => {
// ...
let response = {
statusCode: 200, // or any other HTTP code
headers: { // optional
"any-http-header" : "my custom header value"
},
body: JSON.stringify(payload) // data returned by the API Gateway endpoint
};
done(null, response); // always return as a success
};
它确实有一些缺点: 必须特别注意错误处理,并将 lambda 函数耦合到 API Gateway 端点; 也就是说,如果您不打算在其他地方使用它,那么这不是什么大问题。