Skip to content

Commit

Permalink
Add diagnostics channel to layers
Browse files Browse the repository at this point in the history
  • Loading branch information
Qard committed Sep 17, 2020
1 parent 5596222 commit 7bdd994
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 0 deletions.
40 changes: 40 additions & 0 deletions lib/router/layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@
var pathRegexp = require('path-to-regexp');
var debug = require('debug')('express: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
Expand Down Expand Up @@ -43,6 +55,7 @@ function Layer(path, options, fn) {
this.params = undefined;
this.path = undefined;
this.regexp = pathRegexp(path, this.keys = [], opts);
this.routingKey = path;

// set fast path flags
this.regexp.fast_star = path === '*'
Expand All @@ -67,9 +80,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);
}
};
Expand All @@ -91,9 +118,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);
}
};
Expand Down
104 changes: 104 additions & 0 deletions test/diagnostics_channel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@

var express = 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('routingKey');
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 express.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 express.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 express.Router();
var inner = new express.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 express.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);
done();
}

router.handle({ url: '/hello/world', method: 'GET' }, { end }, noop);
});
});

0 comments on commit 7bdd994

Please sign in to comment.