diff --git a/src/plugins/express.js b/src/plugins/express.js index 2ae0e7974af..3a6f7c80e32 100644 --- a/src/plugins/express.js +++ b/src/plugins/express.js @@ -97,11 +97,11 @@ function createWrapRouterMethod (tracer) { const handleError = layer.handle_error layer.handle_request = (req, res, next) => { - return handleRequest.call(layer, req, res, wrapNext(tracer, req, next)) + return handleRequest.call(layer, req, res, wrapNext(tracer, layer, req, next)) } layer.handle_error = (error, req, res, next) => { - return handleError.call(layer, error, req, res, wrapNext(tracer, req, next)) + return handleError.call(layer, error, req, res, wrapNext(tracer, layer, req, next)) } layer._datadog_matchers = matchers @@ -112,8 +112,21 @@ function createWrapRouterMethod (tracer) { } } -function wrapNext (tracer, req, next) { +function wrapNext (tracer, layer, req, next) { if (req._datadog_trace_patched) { + const context = tracer._context + const originalNext = next + + next = context.bind(function () { + const paths = context.get('express.paths') + + if (paths && layer.path && !layer.regexp.fast_star) { + paths.pop() + } + + originalNext.apply(null, arguments) + }) + return tracer._context.bind(next) } diff --git a/test/plugins/express.spec.js b/test/plugins/express.spec.js index cc29651a0f7..37e10d7ef1a 100644 --- a/test/plugins/express.spec.js +++ b/test/plugins/express.spec.js @@ -140,6 +140,38 @@ describe('Plugin', () => { }) }) + it('should only keep the last matching path of a middleware stack', done => { + const app = express() + const router = express.Router() + + router.use('/', (req, res, next) => next()) + router.use('*', (req, res, next) => next()) + router.use('/bar', (req, res, next) => next()) + router.use('/bar', (req, res, next) => { + res.status(200).send() + }) + + app.use('/', (req, res, next) => next()) + app.use('*', (req, res, next) => next()) + app.use('/foo/bar', (req, res, next) => next()) + app.use('/foo', router) + + getPort().then(port => { + agent + .use(traces => { + expect(traces[0][0]).to.have.property('resource', '/foo/bar') + }) + .then(done) + .catch(done) + + appListener = app.listen(port, 'localhost', () => { + axios + .get(`http://localhost:${port}/foo/bar`) + .catch(done) + }) + }) + }) + it('should support asynchronous routers', done => { const app = express() const router = express.Router()