Serverless framework - handler is not a function

73 views Asked by At

I am not sure what exactly is going on, I have done changes to aid for top-level await feature and thus i enabled es2022 and adjusted the webpack accordingly, but after that, when i try to run serverless locally, i get an error that my handlers are not functions even tho i have confirmed that they are being compiled and generated using webpack.

Dependency versions:

    "serverless-api-gateway-throttling": "^1.2.1",
    "serverless-domain-manager": "^5.2.0",
    "serverless-dotenv-plugin": "^3.10.0",
    "serverless-mocha-plugin": "^1.12.0",
    "serverless-offline": "^8.3.1",
    "serverless-plugin-datadog": "^3.4.0",
    "serverless-webpack": "^5.6.0",
    "ts-loader": "^6.2.1",
    "ts-mocha": "^8.0.0",
    "typescript": "^4.5.4",
    "webpack": "^5.65.0",
    "webpack-node-externals": "^3.0.0"

Error:

offline: Failure: offline: handler 'Status' in /Users/mohammed.faour/Desktop/services/reliability-api/.webpack/service/src/main is not a function

My webpack setup looks like this:

/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
const slsw = require('serverless-webpack');
const nodeExternals = require('webpack-node-externals');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
  context: __dirname,
  mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
  entry: slsw.lib.entries,
  devtool: slsw.lib.webpack.isLocal
    ? 'eval-cheap-module-source-map'
    : 'source-map',
  resolve: {
    extensions: ['.mjs', '.json', '.ts'],
    symlinks: false,
    cacheWithContext: false,
    mainFields: ['main', 'module'], // Merged this line from your second resolve property
  },
  output: {
    libraryTarget: 'commonjs',
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js',
  },
  target: 'node',
  externals: [nodeExternals(), 'datadog-lambda-js', 'dd-trace'],
  module: {
    rules: [
      // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
      {
        test: /\.(tsx?)$/,
        loader: 'ts-loader',
        exclude: [
          path.resolve(__dirname, 'node_modules'),
          path.resolve(__dirname, '.serverless'),
          path.resolve(__dirname, '.webpack'),
        ],
        options: {
          transpileOnly: true,
          experimentalWatchApi: true,
        },
      },
      {
        test: /\.(p12)$/i,
        loader: 'file-loader',
        options: { outputPath: 'files' },
      },
    ],
  },
  plugins: [
    new CopyWebpackPlugin({
      patterns: [{ from: 'src/static', to: 'static' }],
    }),
  ],
  node: {
    global: true,
    __filename: true,
    __dirname: true,
  },
};

and my ts_config:

{
  "compilerOptions": {
    "esModuleInterop": true,
    "strict": true,
    "module": "ES2022",
    "removeComments": true,
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "sourceMap": true,
    "outDir": ".build"
  },
  "typeRoots": ["node_modules/@types"],
  "include": ["./**/*.ts"],
  "exclude": [
    "node_modules/**/*",
    "tests/**/*",
    "test/**/*",
    ".serverless/**/*",
    ".webpack/**/*",
    "_warmup/**/*",
    ".vscode/**/*",
    "infra/**/*"
  ]
}

Serverless.yml

functions:
  Status:
    handler: src/main.Status
    events:
      - http:
          method: get
          cors:
            origin: '*'
            headers: ${self:custom.corsAllowedHeaders}
          path: status
          request:
            parameters:
              querystrings:
                param1: true
  DriverRisk:
    handler: src/main.DriverRisk
    events:
      - http:
          method: post
          cors:
            origin: '*'
            headers: ${self:custom.corsAllowedHeaders}
          
  FICO:
    handler: src/main.FICO
    events:
      - http:
          method: post
          cors:
            origin: '*'
            headers: ${self:custom.corsAllowedHeaders}
          
  FICOv2:
    handler: src/main.FICOv2
    events:
      - http:
          method: post
          cors:
            origin: '*'
            headers: ${self:custom.corsAllowedHeaders}
          

main.ts:

import "source-map-support/register";
import { config } from "dotenv";

import StatusHandler from "./handlers/status.handler";
import DriverRiskHandlerV1 from "./handlers/driverRisk.v1.handler";
import FICOHandlerV1 from "./handlers/fico.v1.handler";
import FICOHandlerV2 from "./handlers/fico.v2.handler";

config();

export const Status = StatusHandler;
export const DriverRisk = DriverRiskHandlerV1;
export const FICO = FICOHandlerV1;
export const FICOv2 = FICOHandlerV2;
0

There are 0 answers