Skip to content

Commit e6abc38

Browse files
BridgeARrochdev
authored andcommitted
fix(tracer): make instrumenting hono middlewares more robust (#6250)
The current implementation expected the onError method to always be present. This is now handled appropriately and fixes the access to the path, in case it is missing. Fixes #6230
1 parent 05f56ab commit e6abc38

File tree

3 files changed

+54
-15
lines changed

3 files changed

+54
-15
lines changed

packages/datadog-instrumentations/src/hono.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,35 @@ function wrapFetch (fetch) {
1717
}
1818
}
1919

20+
function onErrorFn (error, _context_) {
21+
throw error
22+
}
23+
2024
function wrapCompose (compose) {
21-
return function (middleware, onError, onNotFound) {
25+
return function (middlewares, onError, onNotFound) {
26+
onError ??= onErrorFn
27+
2228
const instrumentedOnError = (...args) => {
2329
const [error, context] = args
2430
const req = context.env.incoming
2531
errorChannel.publish({ req, error })
2632
return onError(...args)
2733
}
2834

29-
const instrumentedMiddlewares = middleware.map(h => {
35+
const instrumentedMiddlewares = middlewares.map(h => {
3036
const [[fn, meta], params] = h
3137

32-
// TODO: handle middleware instrumentation
3338
const instrumentedFn = (...args) => {
3439
const context = args[0]
35-
const req = context.env.incoming
36-
const route = meta.path
3740
routeChannel.publish({
38-
req,
39-
route
41+
req: context.env.incoming,
42+
route: meta?.path
4043
})
4144
return fn(...args)
4245
}
4346
return [[instrumentedFn, meta], params]
4447
})
45-
return compose.apply(this, [instrumentedMiddlewares, instrumentedOnError, onNotFound])
48+
return compose.call(this, instrumentedMiddlewares, instrumentedOnError, onNotFound)
4649
}
4750
}
4851

packages/datadog-plugin-hono/test/integration-test/client.spec.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ const {
88
assertObjectContains,
99
} = require('../../../../integration-tests/helpers')
1010

11-
describe('esm', () => {
11+
describe('esm integration test', () => {
1212
let agent
1313
let proc
1414
let sandbox
1515

16-
withVersions('hono', 'hono', version => {
16+
withVersions('hono', 'hono', (range, _moduleName_, version) => {
1717
before(async function () {
1818
this.timeout(50000)
19-
sandbox = await createSandbox([`'hono@${version}'`, '@hono/[email protected]'], false,
19+
sandbox = await createSandbox([`'hono@${range}'`, '@hono/[email protected]'], false,
2020
['./packages/datadog-plugin-hono/test/integration-test/*'])
2121
})
2222

@@ -35,13 +35,25 @@ describe('esm', () => {
3535
})
3636

3737
it('is instrumented', async () => {
38-
proc = await spawnPluginIntegrationTestProc(sandbox.folder, 'server.mjs', agent.port)
38+
proc = await spawnPluginIntegrationTestProc(sandbox.folder, 'server.mjs', agent.port, undefined, {
39+
VERSION: version
40+
})
3941
proc.url += '/hello'
4042

4143
return curlAndAssertMessage(agent, proc, ({ headers, payload }) => {
4244
assertObjectContains(headers, { host: `127.0.0.1:${agent.port}` })
43-
// TODO: Fix the resource! It should be 'GET /hello'
44-
// This seems to be a generic ESM issue, also e.g., on express.
45+
assertObjectContains(payload, [[{ name: 'hono.request', resource: 'GET /hello' }]])
46+
})
47+
}).timeout(50000)
48+
49+
it('receives missing route trace', async () => {
50+
proc = await spawnPluginIntegrationTestProc(sandbox.folder, 'server.mjs', agent.port, undefined, {
51+
VERSION: version
52+
})
53+
proc.url += '/missing'
54+
55+
return curlAndAssertMessage(agent, proc, ({ headers, payload }) => {
56+
assertObjectContains(headers, { host: `127.0.0.1:${agent.port}` })
4557
assertObjectContains(payload, [[{ name: 'hono.request', resource: 'GET' }]])
4658
})
4759
}).timeout(50000)

packages/datadog-plugin-hono/test/integration-test/server.mjs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,34 @@ import 'dd-trace/init.js'
22
import { Hono } from 'hono'
33
import { serve } from '@hono/node-server'
44

5+
import process from 'node:process'
6+
57
const app = new Hono()
68

9+
const version = process.env.VERSION.split('.').map(Number)
10+
11+
const hasCombine = version[0] > 4 || version[0] === 4 && version[1] >= 5
12+
const response = 'green energy\n'
13+
14+
if (hasCombine) {
15+
const { every } = await import('hono/combine')
16+
app.use(every(async (context, next) => {
17+
context.set('response', response)
18+
return next()
19+
}))
20+
} else {
21+
app.use(async (context, next) => {
22+
context.set('response', response)
23+
return next()
24+
})
25+
}
26+
727
app.get('/hello', (c) => {
8-
return c.text('green energy\n')
28+
const res = c.get('response')
29+
if (res !== response) {
30+
throw new Error(`Expected response to be "${response}", got "${res}"`)
31+
}
32+
return c.text(res)
933
})
1034

1135
serve({

0 commit comments

Comments
 (0)