Hi guys, I am trying to create a discord bot using...
# help
m
Hi guys, I am trying to create a discord bot using the discord.js library. Locally with
sst start
it works fine, but when I try to deploy it, it complains about an external module called ffmpeg-static. If I add this library to the externalModules property of the bundle, the deploy works, but my function does not work when I call the url, it complains about the following… (will put inside the thread). Does anybody have a clue of what might be happening? Thanks a lot in advance!
Copy code
{
  "errorType": "Runtime.UnhandledPromiseRejection",
  "errorMessage": "TypeError: AbortController is not a constructor",
  "reason": {
    "errorType": "TypeError",
    "errorMessage": "AbortController is not a constructor",
    "code": 500,
    "name": "TypeError",
    "method": "get",
    "path": "/gateway/bot",
    "stack": [
      "TypeError: AbortController is not a constructor",
      "    at RequestHandler.execute (/var/task/lambda.js:12126:17)",
      "    at RequestHandler.execute (/var/task/lambda.js:12129:21)",
      "    at RequestHandler.push (/var/task/lambda.js:12092:27)",
      "    at async WebSocketManager2.connect (/var/task/lambda.js:23669:11)",
      "    at async Client.login (/var/task/lambda.js:24346:9)"
    ]
  },
  "promise": {},
  "stack": [
    "Runtime.UnhandledPromiseRejection: TypeError: AbortController is not a constructor",
    "    at process.<anonymous> (/var/runtime/index.js:35:15)",
    "    at process.emit (events.js:314:20)",
    "    at processPromiseRejections (internal/process/promises.js:209:33)",
    "    at processTicksAndRejections (internal/process/task_queues.js:98:32)"
  ]
}
f
Hey @Manoel Feliciano, try using
nodeModules
instead of
externalModules
m
Will give it a try, thanks for the quick response Frank!
f
np! Modules listed in
externalModules
are excluded from the package. Where as with
nodeModules
, the modules are not bundled by esbuild, but included as in with the Lambda code.
m
When I do this, it asked me to install the library so it could be added in package.json.
Even though this worked for the deploy, I still get the same error 😞 I don’t know why it works locally with
sst start
though…
f
you should see a
.build
folder in your app’s directory
can you show me what’s inside
.build/cdk.out
?
(^Ur code is run locally with
sst start
, and since
ffmpeg-static
is installed locally, ur code runs fine. Where as with
sst deploy
, ur code is packaged and sent to Lambda, and it’s probably not packaging
ffmpeg-static
correctly, hence the error)
m
Hmmm, I see. I will paste the cdk.out here.
f
oh i mean, can you show me an
ls
of what’s inside the
cdk.out
folder?
m
Sure.
Copy code
total 152
drwxr-xr-x   8 manoelfeliciano  staff    256  5 Jul 18:55 .
drwxr-xr-x  11 manoelfeliciano  staff    352  5 Jul 19:05 ..
drwxr-xr-x   3 manoelfeliciano  staff     96  5 Jul 18:55 .cache
drwxr-xr-x   7 manoelfeliciano  staff    224  5 Jul 18:55 asset.6624c5951b2e51ab2be1a1bac1fea422e47d1aa8c12a3820d4e8514b464eeccd
-rw-r--r--   1 manoelfeliciano  staff     20  5 Jul 18:55 cdk.out
-rw-r--r--   1 manoelfeliciano  staff  35699  5 Jul 18:55 manifest.json
-rw-r--r--   1 manoelfeliciano  staff   9727  5 Jul 18:55 prod-discord-bot-discord-bot-stack.template.json
-rw-r--r--   1 manoelfeliciano  staff  23001  5 Jul 18:55 tree.json
f
So
asset.6624c5951b2e51ab2be1a1bac1fea422e47d1aa8c12a3820d4e8514b464eeccd
is the packaged Lambda code. Can you do an
ls
in there?
m
Here it goes:
Copy code
total 4088
drwxr-xr-x   7 manoelfeliciano  staff      224  5 Jul 18:55 .
drwxr-xr-x   8 manoelfeliciano  staff      256  5 Jul 18:55 ..
-rw-r--r--   1 manoelfeliciano  staff   776985  5 Jul 18:55 lambda.js
-rw-r--r--   1 manoelfeliciano  staff  1298513  5 Jul 18:55 lambda.js.map
drwxr-xr-x  26 manoelfeliciano  staff      832  5 Jul 18:55 node_modules
-rw-r--r--   1 manoelfeliciano  staff       44  5 Jul 18:55 package.json
-rw-r--r--   1 manoelfeliciano  staff     6655  5 Jul 18:55 yarn.lock
f
right, and since u have
nodeModules
configured,
ffmpeg-static
should be packaged separately into
node_modules
Can you do an
ls
in
node_modules
?
m
Yeah:
Copy code
@derhuerst           core-util-is         inherits             readable-stream
@types               debug                isarray              safe-buffer
agent-base           env-paths            ms                   string_decoder
buffer-from          ffmpeg-static        parse-cache-control  typedarray
caseless             http-response-object process-nextick-args util-deprecate
concat-stream        https-proxy-agent    progress
f
hmm it’s there
You are still getting the
TypeError: AbortController is not a constructor
error?
m
Unfortunately, yes… But it works in
sst start
.
f
Which package is
AbortController
coming from?
m
Comes from a node_modules called abort-controller. Which is quite interesting, after adding it locally to package.json and additing to that node_modules property the error is gone. But I get another one:
Copy code
{
  "errorType": "Runtime.UnhandledPromiseRejection",
  "errorMessage": "TypeError: fetch is not a function",
  "reason": {
    "errorType": "TypeError",
    "errorMessage": "fetch is not a function",
    "code": 500,
    "name": "TypeError",
    "method": "get",
    "path": "/gateway/bot",
    "stack": [
      "TypeError: fetch is not a function",
      "    at RequestHandler.execute (/var/task/lambda.js:12049:17)",
      "    at RequestHandler.execute (/var/task/lambda.js:12052:21)",
      "    at RequestHandler.push (/var/task/lambda.js:12015:27)",
      "    at async WebSocketManager2.connect (/var/task/lambda.js:23592:11)",
      "    at async Client.login (/var/task/lambda.js:24269:9)"
    ]
  },
  "promise": {},
  "stack": [
    "Runtime.UnhandledPromiseRejection: TypeError: fetch is not a function",
    "    at process.<anonymous> (/var/runtime/index.js:35:15)",
    "    at process.emit (events.js:314:20)",
    "    at processPromiseRejections (internal/process/promises.js:209:33)",
    "    at processTicksAndRejections (internal/process/task_queues.js:98:32)"
  ]
}
Do you know what may be causing this?
Having me the need to add this packages manually?
f
hmm.. can I see your package.json and ur lambda code?
Feel free to DM me if that works better for u.
m
Sure. Thanks a lot for the help in advance!
If anybody find this and wonder why it was not working, I needed to do the following:
Copy code
const api = new sst.Api(this, 'Api', {
			defaultFunctionProps: {
				bundle: {
					nodeModules: ['discord.js'],
				},
			},
			routes: {
				'POST /': 'src/lambda.handler',
			},
		});
Needed to add the discord.js in nodeModules property inside bundle.
f
Thanks @Manoel Feliciano for sharing it!
Yeah, so the root cause of the issue is that
discord.js
dynamically imports some modules internally (ie.
node-fetch
,
abort-controller
, etc), and these modules are not getting bundled.
The solution here would be to package
discord.js
as a node module, and this will ensure it and all of its dependencies are packaged with the Lambda code.