dherault / serverless-offline

Emulate AWS λ and API Gateway locally when developing your Serverless project
MIT License
5.2k stars 794 forks source link

One of the module nesting for handler is undefined #1377

Closed prxg22 closed 2 years ago

prxg22 commented 2 years ago

Bug Report

Current Behavior I'm currently deploying a Remix app with serverless and using serverless-offline to run my app on development environment (highly inspired by @shamsup). It worked fine until v8.5, but since v8.6 I'm experiencing this bug every time I send a request to the remix lambda.

[offline] Loading handler... (/Users/prxg/Developer/labs/remix-starter-serverless/.esbuild/.build/server/index)
(node:60712) UnhandledPromiseRejectionWarning: Error: offline: one of the module nesting [object Object] for handler handler is undefined or not exported
    at InProcessRunner.run (/Users/prxg/Developer/labs/remix-starter-serverless/node_modules/serverless-offline/dist/lambda/handler-runner/in-process-runner/InProcessRunner.js:171:13)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at process.<anonymous> (/Users/prxg/Developer/labs/remix-starter-serverless/node_modules/serverless-offline/dist/lambda/handler-runner/child-process-runner/childProcessHelper.js:37:18)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:60712) 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(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:60712) [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.

The handler is essentially created by @remix-run/architect, but I'm not sure what it does behind the scenes.

Sample Code I created this example repo to reproduce the error. If you try to run npm run dev and access http://localhost:3000 the error will pop up on your server console and the server will crash. If you downgrade serverless-offline to v8.5 version, the application will be served successfully.

Expected behavior/code It should respond to the http request correctly

Environment

dherault commented 2 years ago

Thanks a lot @prxg22 for the repo, taking a look

atrudeau-vitall commented 2 years ago

+1

destbreso commented 2 years ago

++

NOTE: same env with sls offline 8.5.0 works fine

zeeshangeekshub commented 2 years ago

I am facing same issue, while trying to initialize Sequelize Connection, if I comment this line const sequelize = new Sequelize(connectionString) out, or basically I skip Sequelize setup, it works as expected (of course without database), but it returns some sensible response. As soon as I try to perform intialization, it again gives me this weird error, with no explanation, where and what is wrong.

Downgrading serverless-offline to 8.5.0 has no effect

db.ts

import { Sequelize } from "sequelize-typescript";
import { User } from "./models/User";

const encodedPassword = encodeURIComponent("some#password");
const connectionString = `postgres://user:${encodedPassword}@host/db`;

const sequelize = new Sequelize(connectionString);

sequelize.addModels([User]);

// export default {sequelize, Sequelize}
export { sequelize, Sequelize };

handler.ts

import * as db from "../db/database";
import type { ValidatedEventAPIGatewayProxyEvent } from "@libs/api-gateway";
import { middyfy } from "@libs/lambda";

const generatePdf: ValidatedEventAPIGatewayProxyEvent<typeof schema> = async (
    event
) => {
const { id } = event.pathParameters;
        // below line cause this error
    await db.sequelize
        .authenticate()
        .then(async () => {
            console.log("::::: DB CONNECTED");
        })
        .catch((err) => console.log(":::: DB ERROR", err));

    // my other logic goes here

    return {
        statusCode: 200,
        body: responseBody,
    };
}
pedrokaroth commented 2 years ago

+1

samwiseduzer commented 2 years ago

+1

ekosinskiy commented 2 years ago

I downgraded serverless-offline to 8.3.1 and mongoose start working. I hope it help. Latest version 8.7.0 - doesn't work for me

mguilhermetavares commented 2 years ago

+1

zeeshangeekshub commented 2 years ago

I have downgraded serverless-offline to 8.3.1 (was 8.5.0), but of no vail, here is my package.json

{
    "name": "serverless-app",
    "version": "1.0.0",
    "description": "Serverless aws-nodejs-typescript template",
    "main": "serverless.ts",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "engines": {
        "node": ">=14.15.0"
    },
    "dependencies": {
        "@middy/core": "^2.5.3",
        "@middy/http-json-body-parser": "^2.5.3",
        "handlebars": "^4.7.7",
        "html-pdf": "^3.0.1",
        "pg-hstore": "^2.3.4",
        "phantomjs-prebuilt": "^2.1.16",
        "reflect-metadata": "^0.1.13",
        "sequelize": "^6.19.0",
        "sequelize-typescript": "^2.1.3",
        "serverless-offline": "^8.3.1",
        "witch": "^1.0.3"
    },
    "devDependencies": {
        "@serverless/typescript": "^3.0.0",
        "@types/aws-lambda": "^8.10.71",
        "@types/node": "^14.14.25",
        "@types/sequelize": "^4.28.11",
        "esbuild": "^0.14.11",
        "json-schema-to-ts": "^1.5.0",
        "serverless": "^3.0.0",
        "serverless-esbuild": "^1.23.3",
        "ts-node": "^10.4.0",
        "tsconfig-paths": "^3.9.0",
        "typescript": "^4.1.3"
    },
    "author": "The serverless webpack authors (https://github.com/elastic-coders/serverless-webpack)",
    "license": "MIT"
}
bfaulk96 commented 2 years ago

+1, 8.5.0 works for my project but anything above breaks with the error that OP shared

ChristianRich commented 2 years ago

My project broke, but after downgrading to 8.5.0 the error went away

mangonecristian commented 2 years ago

Same here, 8.5.0 didn't work.

akinboboye commented 2 years ago

I am looking into this too.

akinboboye commented 2 years ago

@prxg22 thank you for the detailed example repo on how to reproduce the error. I see what the issue is and would be submitting a fix in the next hour.

The issue - when i made an update for serverless-offline to use nested handler modules I missed updating the childProcessHelper file. And because you are using the offline flag -useChildProcess, it was calling the file childProcessHelper which was missed in my changes.

I sincerely apologize for the inconveniences. I will write up the fix and link it to this issue.

Are you able to please test when the PR is open ?

prxg22 commented 2 years ago

@akinboboye I'll be happy to help you testing the PR 😉

akinboboye commented 2 years ago

@prxg22 the PR referenced above should fix the issue you were having. Could you please confirm that ?

prxg22 commented 2 years ago

@akinboboye I tested both using and not using --useChildProcesses flag. They both worked perfectly. Thank you (:

devadeboye commented 2 years ago

I had the same problem in my project that contains nestjs with serverless-offline 8.7.0. it seems the 8.7.0 version returns ambiguous error message. Downgrading to 8.5.0 solves my problem

joaocasarin commented 2 years ago

Hi all, in this project: repo

I have tried with both serverless-offline 8.7.0, 8.5.0 and 8.31.

When using 8.7.0 I have a smiliar error as the OP: image

And when using both 8.5.0 and 8.3.1 I have this error: image

To reproduce you need basically to follow the readme, but here are the steps:

$ docker-compose --env-file .env.example up -d
$ yarn install
$ yarn db:migrate
$ serverless offline

Then you should try hitting localhost:3000/dev/create-user using POST with a body request as following:

{
  "name": "john",
  "age": 10,
  "password": "1234"
}

Any idea here?

Thanks

MathRobin commented 2 years ago

Had the same error, found that I had a syntaxic error not detected by eslint (hell!!), a module was used before declared. Found it when trying to run my tests which failed of course. When fixed, everything goes normal again

kenlfg commented 2 years ago

I had this same problem but it occurred after upgrading from v8.4.0. Downgrading back to v8.4.0 made it go away. With it upgraded back to 8.7.0, if I turn off the useChildProcesses setting (set to false) the error goes away as well. I can't for the life of me remember why I needed that setting set to true (there was some reason many versions ago--I just never set it back to false).

So if you're having this issue and you have that setting turned on, try turning it off useChildProcesses: false.

Dilven commented 2 years ago

To debug this, do a serverless package and check what is packaged in the zip-archive (in the .serverless directory). You can try extracting the zip-archive and do a node ./.serverless/handlers/your-handler.js then you should see more information what it's going on

bdanzer commented 2 years ago

I had this same problem but it occurred after upgrading from v8.4.0. Downgrading back to v8.4.0 made it go away. With it upgraded back to 8.7.0, if I turn off the useChildProcesses setting (set to false) the error goes away as well. I can't for the life of me remember why I needed that setting set to true (there was some reason many versions ago--I just never set it back to false).

So if you're having this issue and you have that setting turned on, try turning it off useChildProcesses: false.

Weirdly enough disabling the child process fixed it for me in the latest version

kotleon1986 commented 2 years ago

Hello. Try adding the following to your serverless.yml file:

custom:
  serverless-offline:
    useChildProcesses: true
tattsun commented 2 years ago

+1 Downgrading serverless-offline to ~8.5.0 works for me.

Mystogab commented 2 years ago

Same issue here, upgraded from 8.4 to 8.7.0 breaks in the way described above. Downgrading to 8.5.0 works fine. Anyway if I will need latest version as we plan to upgrade to AWS lambda runtime node16.x. And with this we are stuck

Mystogab commented 2 years ago

@dherault could you give us a hand here? In my case I rise up a local env with lambdas that call another lambdas (through aws-sdk v3) using endpoint: "http://localhost:3002" That use to work great before 8.6.0 release. Actually I cant go beyond 8.5.0, withouth breaking my local env.

Mystogab commented 2 years ago

As the error stack suggest lambda > handler-runner > in-process-runner > InProcessRunner.js > run, where we can see the error throwing:

let handler
    try {
      const handlerPathExport = await import(this.#handlerPath)
      // this supports handling of nested handler paths like <pathToFile>/<fileName>.object1.object2.object3.handler
      // a use case for this, is when the handler is further down the export tree or in nested objects
      // NOTE: this feature is supported in AWS Lambda
      handler = this.#handlerModuleNesting.reduce(
        (obj, key) => obj[key],
        handlerPathExport,
      )
    } catch (error) {
      throw new Error(
        `offline: one of the module nesting ${
          this.#handlerModuleNesting
        } for handler ${this.#handlerName} is undefined or not exported`,
      )
    }

So it bug seems to be introduced by handlerModuleNesting feature if that helps

Mystogab commented 2 years ago

update: Working on serverless-offline 8.8.0 I saw a regration changelog. Now local enviroment runs ok again with multiple lambda invoking other lambdas.

MrDavidson23 commented 2 years ago

Hey guys, I was having the same error, my workaround for this was to upgrade serverless-offline to "serverless-offline": "8.8.0", in the package.json, run npm install and the error was different, it says that it cannot find a module, so I changed the path from absolute path to relative path and that worked just fine for me Hope it works for you too

davidsmej88 commented 2 years ago

Hi guys, same problem here. I tried to upgrade serverless-offline to "serverless-offline": "8.8.0, but now I have new error

× Unexpected token u in JSON at position 0
× SyntaxError: Unexpected token u in JSON at position 0
dnalborczyk commented 2 years ago

this issue was reverted in v8.8.0. feel free to open a new issue if there's still a problem.