-
-
Notifications
You must be signed in to change notification settings - Fork 118
Use diagnostics_channel in layers #96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,18 @@ | |
| var pathRegexp = require('path-to-regexp') | ||
| var debug = require('debug')('router:layer') | ||
|
|
||
| /** | ||
| * Diagnostic channels | ||
| * @private | ||
| */ | ||
| var onHandleRequest | ||
| var onHandleError | ||
| try { | ||
| var dc = require('diagnostics_channel') | ||
| onHandleRequest = dc.channel('express.layer.handle_request') | ||
| onHandleError = dc.channel('express.layer.handle_error') | ||
| } catch (err) { } | ||
|
|
||
| /** | ||
| * Module variables. | ||
| * @private | ||
|
|
@@ -41,6 +53,7 @@ function Layer(path, options, fn) { | |
| this.params = undefined | ||
| this.path = undefined | ||
| this.regexp = pathRegexp(path, this.keys = [], opts) | ||
| this.routingPath = path | ||
|
|
||
| // set fast path flags | ||
| this.regexp.fast_star = path === '*' | ||
|
|
@@ -65,9 +78,23 @@ Layer.prototype.handle_error = function handle_error(error, req, res, next) { | |
| return next(error) | ||
| } | ||
|
|
||
| req.layerStack = req.layerStack || [] | ||
|
||
| req.layerStack.push(this) | ||
|
|
||
| if (onHandleError && onHandleError.shouldPublish()) { | ||
| onHandleError.publish({ | ||
| error: error, | ||
| request: req, | ||
| response: res, | ||
| layer: this | ||
| }) | ||
| } | ||
|
|
||
| try { | ||
| fn(error, req, res, next) | ||
| req.layerStack.pop() | ||
| } catch (err) { | ||
| req.layerStack.pop() | ||
|
||
| next(err) | ||
| } | ||
| } | ||
|
|
@@ -89,9 +116,22 @@ Layer.prototype.handle_request = function handle(req, res, next) { | |
| return next() | ||
| } | ||
|
|
||
| req.layerStack = req.layerStack || [] | ||
| req.layerStack.push(this) | ||
|
|
||
| if (onHandleRequest && onHandleRequest.shouldPublish()) { | ||
| onHandleRequest.publish({ | ||
| request: req, | ||
| response: res, | ||
| layer: this | ||
| }) | ||
| } | ||
|
|
||
| try { | ||
| fn(req, res, next) | ||
| req.layerStack.pop() | ||
| } catch (err) { | ||
| req.layerStack.pop() | ||
| next(err) | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
|
|
||
| var Router = require('../') | ||
| , assert = require('assert'); | ||
|
|
||
| var dc = require('diagnostics_channel'); | ||
| var onHandleRequest = dc.channel('express.layer.handle_request'); | ||
| var onHandleError = dc.channel('express.layer.handle_error'); | ||
|
|
||
| function mapProp(prop) { | ||
| return function mapped(obj) { | ||
| return obj[prop]; | ||
| }; | ||
| } | ||
|
|
||
| function mapAndJoin(prop) { | ||
| return function (list) { | ||
| return list.map(mapProp(prop)).join(''); | ||
| } | ||
| } | ||
|
|
||
| function noop() { } | ||
|
|
||
| describe('diagnostics_channel', function () { | ||
| var joinLayerStack = mapAndJoin('routingPath'); | ||
| var handleRequest; | ||
| var handleError; | ||
|
|
||
| onHandleRequest.subscribe(function (message) { | ||
| handleRequest = message; | ||
| }); | ||
|
|
||
| onHandleError.subscribe(function (message) { | ||
| handleError = message; | ||
| }); | ||
|
|
||
| it('use has no layers with a path', function (done) { | ||
| var router = new Router(); | ||
|
|
||
| router.use(function (req, res) { | ||
| res.end(); | ||
| }); | ||
|
|
||
| function end() { | ||
| assert.strictEqual(joinLayerStack(handleRequest.request.layerStack), '/'); | ||
| done(); | ||
| } | ||
|
|
||
| router.handle({ url: '/', method: 'GET' }, { end }, noop); | ||
| }); | ||
|
|
||
| it('regular routes have a layer with a path', function (done) { | ||
| var router = new Router(); | ||
|
|
||
| router.get('/hello/:name', function (req, res) { | ||
| res.end(); | ||
| }); | ||
|
|
||
| function end() { | ||
| assert.strictEqual(joinLayerStack(handleRequest.request.layerStack), '/hello/:name/'); | ||
| done(); | ||
| } | ||
|
|
||
| router.handle({ url: '/hello/world', method: 'GET' }, { end }, noop); | ||
| }); | ||
|
|
||
| it('nested routes have multiple layers with paths', function (done) { | ||
| var outer = new Router(); | ||
| var inner = new Router(); | ||
|
|
||
| inner.get('/:name', function (req, res) { | ||
| res.end(); | ||
| }); | ||
|
|
||
| outer.use('/hello', inner); | ||
|
|
||
| function end() { | ||
| assert.strictEqual(joinLayerStack(handleRequest.request.layerStack), '/hello/:name/'); | ||
| done(); | ||
| } | ||
|
|
||
| outer.handle({ url: '/hello/world', method: 'GET' }, { end }, noop); | ||
| }); | ||
|
|
||
| it('errors send through a different channel', function (done) { | ||
| var router = new Router(); | ||
| var error = new Error('fail'); | ||
|
|
||
| router.get('/hello/:name', function (req, res) { | ||
| throw error; | ||
| }); | ||
|
|
||
| router.use(function (err, req, res, next) { | ||
| res.end(); | ||
| }); | ||
|
|
||
| function end() { | ||
| assert.strictEqual(joinLayerStack(handleRequest.request.layerStack), '/hello/:name/'); | ||
| assert.strictEqual(handleError.error, error); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this validate that the handle error layer stack is pointing to the
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure we should be treating error handlers as top-level routes, that's an implementation detail. It makes more sense from the APM perspective to treat them as continuations of whatever route the error handler was reached from.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, interesting. I was assuming your wanted the layer stack to be the current stack of layers--you didn't note that certain layers were going to be treated differently. That is likely a very important point that was left out of your explanation. So you are saying that even an error handler that is itself a route would not be listed? I.e.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Taking a look, I'm not sure if this behavior is why the following will generate a layer stack showing the "route" is var router = new Router();
router.get('/hello/:name', (req, res, next) => {
if (!isNaN(Number(req.params.name))) next('route')
else next()
}, (req, res) => {
res.end()
});
router.get('/hello/100', (req, res) => {
res.end()
}) |
||
| done(); | ||
| } | ||
|
|
||
| router.handle({ url: '/hello/world', method: 'GET' }, { end }, noop); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just as a general comment: I'm not sure if you planed to clean this up later, so apologies if so, just wanted to call out that we don't want to be passing in mock-like objects to the router handling methods; they should be the real Node.js HTTP objects like all the other tests so we validate that everything is working as new Node.js versions come out and these objects change over time.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, the changes are all copied and pasted from the PR I made directly to express, which apparently did tests differently. I'll clean up the tests at some point, when I get back to this. 👍 |
||
| }); | ||
| }); | ||
Uh oh!
There was an error while loading. Please reload this page.