Lambda function in production getting "Process exited before completing request", but works fine in development

I am using netlify-lambda to build the current lambda-function

const https = require('https');
const env = require('dotenv').config();
var querystring = require('querystring');

const redirectUri = "http://example.no";
exports.handler = function(event, context, callback) {
    let formData = new URLSearchParams();
    formData.append('code', event.queryStringParameters.code);
    formData.append('redirect_uri', redirectUri);
    formData.append('grant_type', 'authorization_code');
    formData.append('client_id', process.env.LINE_REITN_CLIENT_ID);
    formData.append('client_secret', process.env.LINE_REITN_CHANNEL_SECRET);
    var postData = querystring.stringify({
        code: event.queryStringParameters.code,
        redirect_uri: redirectUri,
        grant_type: 'authorization_code',
        client_id: process.env.LINE_REITN_CLIENT_ID,
        client_secret: process.env.LINE_REITN_CHANNEL_SECRET
    });
    const options = {
        hostname: 'api.line.me',
        port: 443,
        path: '/oauth2/v2.1/token',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': postData.length
        }
    };
    const req = https.request(options, (res) => {
        res.on('data', (d) => {
            callback(null,{
                statusCode: 200,
                body: d
            });
        });
        res.on('error', (e) => {
            callback(null, {
                statusCode: 500,
                body: 'noe skjedde feil'
            });
        });
    });
    
    req.on('error', (e) => {
        callback(null, {
            statusCode: 500,
            body: 'feil'
        });
    });
    req.write(postData);
    req.end();
}

This works very well in development, but in production I get the following error message:
{"errorMessage":"RequestId: 7f11a187-b549-466d-ba17-c93263c86e6b Process exited before completing request"}.

I am not sure why I am getting this error message, and I do not know how to fix it. Has anyone experienced something similar?

Netlify has a 10 second limit (by default) on Lambdas, so it’s possible this is coming up due to a timing out Lambda. Locally, the netlify-lambda serve command tries to mimic this 10s limit, but only really approximates it.

I don’t think it is a timeout issue, because I receive the error within two seconds tops.

I have modified my code a bit, using async, and return new Promise. Which seems to make the application work. I also had some unused code (the formData). I was getting an error saying that URLSearchParams was undefined or something similar, so I removed it. Here is the updated code that works in production as well.

const https = require('https');
const env = require('dotenv').config();
var querystring = require('querystring');

exports.handler = async (event, context) => { // using async instead of callback
    let redirectUri = "http://example.no";
    var postData = querystring.stringify({
        code: event.queryStringParameters.code,
        redirect_uri: redirectUri,
        grant_type: 'authorization_code',
        client_id: process.env.LINE_REITN_CLIENT_ID,
        client_secret: process.env.LINE_REITN_CHANNEL_SECRET
    });
    const options = {
        hostname: 'api.line.me',
        port: 443,
        path: '/oauth2/v2.1/token',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': postData.length
        }
    };
    return new Promise((resolve, reject) => { // using Promise
        const req = https.request(options, (res) => {
            res.on('data', (d) => {
                resolve({
                    statusCode: 200,
                    body: d.toString() // added toString()
                });
            });
            res.on('error', (e) => {
                resolve({
                    statusCode: 500,
                    body: 'noe skjedde feil'
                });
            });
        });

        req.on('error', (e) => {
            resolve({
                statusCode: 500,
                body: 'feil'
            });
        });
        req.write(postData);
        req.end();
    });
}

Ahh yeah, so it looks like the issue was that your JS code was throwing and exiting, and therefore never called callback (due to the error-exit) and that’s the message that it “exited before completing the request” I guess.

Changing it to async style works because any uncaught exceptions will “reject” the promise and (presumably) the code that orchestrates your handler will catch that and respond to the API gateway appropriately.

That may be the case. I still wonder why the behaviour was different from development and production though. I use netlify-lambda to build the functions in my local development environment as well as on Netlify’s server. I also set the environment variable NODE_VERSION = 12.4.0 to make sure that I am running the same node version locally, and on the server.

Server only supports Node 8 or Node 10 AFAIK (certainly I’m pretty sure Lambda only supports those officially in the images).

As for why it works locally, at a guess, because netlify-lambda is running your code in a normal node process, whereas on the server it’s being orchestrated in some form (looking at another recent thread’s reported errors, through Go), and Netlify haven’t handled the case of an erroring JS app (that doesn’t use promises) very well.

Unless you don’t mean local dev when you say “in development”.

1 Like