dd-trace-js
dd-trace-js copied to clipboard
Express hook not called when using ES modules
Describe the bug
When using esm the express request hook is not getting called. Whereas when using CommonJS the hook gets called as expected.
Minimal example for reproduction
index.ts
import './tracer.js'
import express from 'express'
const app = express()
app.get(
'/foo',
(req, res) => {
(req as any).foo = 'bar'
return res.send('bar')
}
)
app.listen(8080, () => {
console.log('App started at port 8080')
})
tracer.ts
import tracer from 'dd-trace'
tracer.init()
tracer.use('express', {
hooks: {
request: (span, req, _) => {
console.log(`express hook: ${(req as any)?.foo}`)
span?.setTag('test', (req as any)?.foo)
},
},
})
export default tracer
tsconfig.json
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
}
}
package.json
{
"name": "ddtrace-hook",
"version": "0.1",
"main": "index.ts",
"private": true,
"type": "module",
"engines": {
"node": "^16.0.0"
},
"scripts": {
"server": "node --loader ts-node/esm ./index.ts"
},
"dependencies": {
"dd-trace": "^2.2.0",
"express": "^4.17.2"
},
"devDependencies": {
"@types/express": "^4.17.13",
"ts-node": "^10.4.0",
"typescript": "^4.5.4"
}
}
Use Case
I want to use the hook to add request specific tags to every request. I also tried to create an express middleware for this, but it seems there is no public api to get the local root span (express.request)
Environment
- Operation system: macOs BigSur
- Node version: 16.13.2
- Tracer version: 2.2.0
Support for ESM requires using our loader on the CLI instead of ts-node/esm. It's also worth noting that it's currently experimental and has known issues with some libraries.
You can use our experimental ESM support by using the following command-line flag:
--loader=dd-trace/loader-hook.mjs
Please let us know in this thread if that resolves this for you.
Hi, thanks for your feedback! I tried adding the the hook, unfortunately without success. I also switched to plain JavaScript to avoid the need for the ts-node loader altogether.
Can you share the new code without TypeScript and with our loader hook? Also, depending on the Node version, the option can be --experimental-loader instead of --loader, although I doubt this would be the issue since you were already using a loader hook.
Sure, I am using node v16.13.2, here is my JS code:
index.js
import './tracer.js'
import express from 'express'
const app = express()
app.get(
'/foo',
(req, res) => {
req.foo = 'bar'
return res.send('bar')
}
)
app.listen(8080, () => {
console.log('App started at port 8080')
})
tracer.ts
import tracer from 'dd-trace'
tracer.init()
tracer.use('express', {
hooks: {
request: (span, req, _) => {
console.log(`express hook: ${req?.foo}`)
span?.setTag('test', req?.foo)
},
},
})
export default tracer
package.json
{
"name": "ddtrace-hook",
"version": "0.1",
"main": "index.js",
"private": true,
"type": "module",
"engines": {
"node": "^16.0.0"
},
"scripts": {
"server": "node --loader dd-trace/loader-hook.mjs ./index.js"
},
"dependencies": {
"dd-trace": "^2.2.0",
"express": "^4.17.2"
}
}
I also tried using --experimental-loader to be sure, but without effect.
Tried this locally and there is definitely a bug. A workaround for now is to put tracer.use() above tracer.init() which seems to fix it at least in the above code.
Thanks a lot for the workaround! Tried it out also in our actual projects and it seems to work now :)
Hi @AlexMetroDigital I've just retested the provided .ts and .js code and everything seems to be working, so I'am going to close the issue. Please feel free to reopen another issue if your issue still persists
Can you add this in the README? Because it seems like the loader still is required for projects using ESM. May be related to https://github.com/DataDog/dd-trace-js/issues/4037 but very hard to trace to this as the root cause when all you get is a cryptic error like 2024-02-08 00:24:32 [server] error: TypeError: Cannot read properties of undefined (reading 'length').
Actually, doesn't work. --loader dd-trace/loader-hook.mjs crashes the application for express 4.18 on node 18.