Search code examples
node.jsasync-awaitaws-lambdaes6-promisenetlify

Why netlify-lambda logs an UnhandledPromiseRejectionWarning when using async/await on Promises?


I'm trying to create a lambda function on Netlify and I'm using their Netlify Lambda CLI for that.

Now, I'm experiencing an issue when using async/await on Promises because it logs an UnhandledPromiseRejectionWarning even though I'm using try/catch.

Here's a demo:

import fetch from "node-fetch";

exports.handler = async function(event, context, callback) {
    try {
        const response = await fetch("https://api.chucknorris.io/jokes/random");
        const data = await response.json();

        callback(null, {
            statusCode: 200,
            body: data.value
        });
    } catch (err) {
        console.error(err);
    }
};

Log:

netlify-lambda: Starting server
Lambda server is listening on 9000
Hash: 533f41e1d4248894ae20
Version: webpack 4.26.1
Time: 966ms
Built at: 11/28/2018 10:59:44 PM
  Asset      Size  Chunks             Chunk Names
test.js  18.3 KiB       0  [emitted]  test
Entrypoint test = test.js
[0] external "stream" 42 bytes {0} [built]
[1] external "zlib" 42 bytes {0} [built]
[2] external "url" 42 bytes {0} [built]
[3] external "http" 42 bytes {0} [built]
[4] external "https" 42 bytes {0} [built]
[5] ./test.js + 1 modules 40.8 KiB {0} [built]
    | ./test.js 1.14 KiB [built]
    | ../node_modules/node-fetch/lib/index.mjs 39.6 KiB [built]
Request from ::1: GET /test
Response with status 200 in 685 ms.
(node:99167) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'statusCode' of undefined
    at callback (/Users/nunoarruda/Desktop/test/node_modules/netlify-lambda/lib/serve.js:22:42)
    at /Users/nunoarruda/Desktop/test/node_modules/netlify-lambda/lib/serve.js:41:21
    at process.internalTickCallback (internal/process/next_tick.js:77:7)
(node:99167) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:99167) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Related GitHub issue: https://github.com/netlify/netlify-lambda/issues/43

Why netlify-lambda logs an UnhandledPromiseRejectionWarning when using async/await on Promises? How can I fix this?


Solution

  • With the new Node.js 8.10 runtime, there are new handler types that can be declared with the “async” keyword or can return a promise directly.

    In the AWS docs the v8.10 supports async/await and the new default at Netlify is now using this version. In the AWS docs, the examples show these two new handler types removing the use of the callback. We should do the same in our functions using Netlify.

    I was able to remove the error message locally using the code below without using the callback:

    import fetch from "node-fetch";
    
    exports.handler = async function(event, context) {
        try {
            const response = await fetch("https://api.chucknorris.io/jokes/random");
            if (!response.ok) { // NOT res.status >= 200 && res.status < 300
                return { statusCode: response.status, body: response.statusText };
            }
            const data = await response.json();
    
            return {
                statusCode: 200,
                body: data.value
                // if you want to return whole json string
                // headers: { 'Content-Type': 'application/json' },
                // body: JSON.stringify(data)
            };
        } catch (err) {
            console.log(err); // output to netlify function log
            return {
                statusCode: 500,
                body: err.message // Could be a custom message or object i.e. JSON.stringify(err)
            };
        }
    };