How do I return errors on an AWS Lambda function written in Node.js through the AWS API Gateway using the Serverless framework?
AWS error callbacks for Node.js do not work as advertised. According to the docs, all one needs to do is ensure custom errors extend the Error prototype. However, after over 10 hours of testing, I've found this is completely untrue.
The only way to return an error callback that will return anything other than {"message": "Internal server error"}
(i.e. if you have your Lambda function triggered from the API gateway) is to callback the error as though it were a success.
TL;DR: callback(errorResponse, null)
does not work, but callback(null, errorResponse)
does.
bfissa
Updated on June 25, 2022Comments
-
bfissa almost 2 years
I'm writing an API for internal use, and for the first time I'm using the serverless framework. I'm writing a Lambda function in Node.js, and using the AWS API Gateway to connect to it.
In some cases I want to return a custom error message, and I'm trying to write a function that would allow me to do that. Right now, any time the Lambda process fails, I get a standard message from the API. In the code, if I try to kill the process using
process.exit(1)
, I get a generic error, even if I've already returned an error usingcallback()
:{ "message": "Internal server error" }
If I don't use
process.exit(1)
, I see the error I returned viacallback()
in the logs, but the process continues, ultimately timing out:{ "message": "Endpoint request timed out" }
I've tried a few different ways of returning an error using the
callback()
method, but so far I haven't been successful. I've tried this method:async function return_error(callback, context, error, returnCode){ console.error("FATAL ERROR: ", error); let ErrorObj = { errorType : "InternalServerError", httpStatus : 500, requestId : context.awsRequestId, errorMessage : error } callback(JSON.stringify(ErrorObj)); process.exit(1); }
and this one:
async function return_error(callback, error, returnCode){ console.error("FATAL ERROR: ", error); callback({ isBase64Encoded: false, statusCode: returnCode, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({"Error Message:": error}) }, null); process.exit(1); }
(Sorry about the minor syntax changes between the two.)
So far, I haven't been able to return any error to the user via the API. My error always get's logged, and the function continues. Any help would be appreciated. Thank you!
For reference, the relevant parts of my serverless.yml file:
service: #Name of service provider: name: aws runtime: nodejs8.10 role: #ARN of Iam role functions: screenshot: handler: #Name of handler timeout: 30 memorySize: 1280 reservedConcurrency: 10 events: - http: method: get path: #path contentHandling: CONVERT_TO_BINARY authorizer: type: aws_iam plugins: - serverless-plugin-chrome - serverless-apigw-binary - serverless-apigwy-binary package: exclude: - node_modules/puppeteer/.local-chromium/** custom: apigwBinary: types: - '*/*'
-
bfissa over 5 yearsNo luck, I'm having the same problem. Just to make sure it wasn't related to the function, I hardcoded a test "error" callback in the main method, but I'm having the same results. It's weird because I'm using
callback
to return the results, and that works fine. -
bfissa about 5 yearsIt's been some time since I worked on this project, but that mirrors my experience as well. Thanks!
-
Harrison Cramer over 3 yearsThank you, this seems to be true. However, this eliminates instances in your Lambda environment where you could log and track errors. How can you get around this?