Skip to content

Commit 7bdd994

Browse files
committed
Add diagnostics channel to layers
1 parent 5596222 commit 7bdd994

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

lib/router/layer.js

+40
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@
1616
var pathRegexp = require('path-to-regexp');
1717
var debug = require('debug')('express:router:layer');
1818

19+
/**
20+
* Diagnostic channels
21+
* @private
22+
*/
23+
var onHandleRequest;
24+
var onHandleError;
25+
try {
26+
var dc = require('diagnostics_channel');
27+
onHandleRequest = dc.channel('express.layer.handle_request');
28+
onHandleError = dc.channel('express.layer.handle_error');
29+
} catch (err) {}
30+
1931
/**
2032
* Module variables.
2133
* @private
@@ -43,6 +55,7 @@ function Layer(path, options, fn) {
4355
this.params = undefined;
4456
this.path = undefined;
4557
this.regexp = pathRegexp(path, this.keys = [], opts);
58+
this.routingKey = path;
4659

4760
// set fast path flags
4861
this.regexp.fast_star = path === '*'
@@ -67,9 +80,23 @@ Layer.prototype.handle_error = function handle_error(error, req, res, next) {
6780
return next(error);
6881
}
6982

83+
req.layerStack = req.layerStack || [];
84+
req.layerStack.push(this);
85+
86+
if (onHandleError && onHandleError.shouldPublish()) {
87+
onHandleError.publish({
88+
error: error,
89+
request: req,
90+
response: res,
91+
layer: this
92+
});
93+
}
94+
7095
try {
7196
fn(error, req, res, next);
97+
req.layerStack.pop();
7298
} catch (err) {
99+
req.layerStack.pop();
73100
next(err);
74101
}
75102
};
@@ -91,9 +118,22 @@ Layer.prototype.handle_request = function handle(req, res, next) {
91118
return next();
92119
}
93120

121+
req.layerStack = req.layerStack || [];
122+
req.layerStack.push(this);
123+
124+
if (onHandleRequest && onHandleRequest.shouldPublish()) {
125+
onHandleRequest.publish({
126+
request: req,
127+
response: res,
128+
layer: this
129+
});
130+
}
131+
94132
try {
95133
fn(req, res, next);
134+
req.layerStack.pop();
96135
} catch (err) {
136+
req.layerStack.pop();
97137
next(err);
98138
}
99139
};

test/diagnostics_channel.js

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
2+
var express = require('../')
3+
, assert = require('assert');
4+
5+
var dc = require('diagnostics_channel');
6+
var onHandleRequest = dc.channel('express.layer.handle_request');
7+
var onHandleError = dc.channel('express.layer.handle_error');
8+
9+
function mapProp(prop) {
10+
return function mapped(obj) {
11+
return obj[prop];
12+
};
13+
}
14+
15+
function mapAndJoin(prop) {
16+
return function(list) {
17+
return list.map(mapProp(prop)).join('');
18+
}
19+
}
20+
21+
function noop() {}
22+
23+
describe('diagnostics_channel', function () {
24+
var joinLayerStack = mapAndJoin('routingKey');
25+
var handleRequest;
26+
var handleError;
27+
28+
onHandleRequest.subscribe(function (message) {
29+
handleRequest = message;
30+
});
31+
32+
onHandleError.subscribe(function (message) {
33+
handleError = message;
34+
});
35+
36+
it('use has no layers with a path', function (done) {
37+
var router = new express.Router();
38+
39+
router.use(function (req, res) {
40+
res.end();
41+
});
42+
43+
function end() {
44+
assert.strictEqual(joinLayerStack(handleRequest.request.layerStack), '/');
45+
done();
46+
}
47+
48+
router.handle({ url: '/', method: 'GET' }, { end }, noop);
49+
});
50+
51+
it('regular routes have a layer with a path', function (done) {
52+
var router = new express.Router();
53+
54+
router.get('/hello/:name', function (req, res) {
55+
res.end();
56+
});
57+
58+
function end() {
59+
assert.strictEqual(joinLayerStack(handleRequest.request.layerStack), '/hello/:name/');
60+
done();
61+
}
62+
63+
router.handle({ url: '/hello/world', method: 'GET' }, { end }, noop);
64+
});
65+
66+
it('nested routes have multiple layers with paths', function (done) {
67+
var outer = new express.Router();
68+
var inner = new express.Router();
69+
70+
inner.get('/:name', function (req, res) {
71+
res.end();
72+
});
73+
74+
outer.use('/hello', inner);
75+
76+
function end() {
77+
assert.strictEqual(joinLayerStack(handleRequest.request.layerStack), '/hello/:name/');
78+
done();
79+
}
80+
81+
outer.handle({ url: '/hello/world', method: 'GET' }, { end }, noop);
82+
});
83+
84+
it('errors send through a different channel', function (done) {
85+
var router = new express.Router();
86+
var error = new Error('fail');
87+
88+
router.get('/hello/:name', function (req, res) {
89+
throw error;
90+
});
91+
92+
router.use(function (err, req, res, next) {
93+
res.end();
94+
});
95+
96+
function end() {
97+
assert.strictEqual(joinLayerStack(handleRequest.request.layerStack), '/hello/:name/');
98+
assert.strictEqual(handleError.error, error);
99+
done();
100+
}
101+
102+
router.handle({ url: '/hello/world', method: 'GET' }, { end }, noop);
103+
});
104+
});

0 commit comments

Comments
 (0)