diff --git a/spec/index.spec.js b/spec/index.spec.js index 12f3c14..c044563 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -409,6 +409,27 @@ describe('index', () => { }); }); + it('handles errors in collectors', done => { + const app = express(); + const instance = bundle({}); + app.use(instance); + + spyOn(console, 'error'); // mute console.error + + new promClient.Gauge({ + name: 'kaboom', + help: 'this metric explodes', + collect() { + throw new Error('kaboom!'); + } + }); + + supertest(app) + .get('/metrics') + .expect(500) + .end((err) => done(err)); + }); + it('customLabels={foo: "bar"} adds foo="bar" label to metrics', done => { const app = express(); const instance = bundle({ diff --git a/src/index.js b/src/index.js index eece637..6f85193 100644 --- a/src/index.js +++ b/src/index.js @@ -140,17 +140,20 @@ function main(opts) { } const metricsMiddleware = function(req, res, next) { - res.writeHead(200, {'Content-Type': 'text/plain'}); + const sendSuccesss = (output) => { + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.end(output); + }; const metricsResponse = opts.promRegistry.metrics(); // starting from prom-client@13 .metrics() returns a Promise if (metricsResponse.then) { metricsResponse - .then(output => res.end(output)) + .then(output => sendSuccesss(output)) .catch(err => next(err)); } else { // compatibility fallback for previous versions of prom-client@<=12 - res.end(metricsResponse); + sendSuccesss(metricsResponse); } }; @@ -161,7 +164,7 @@ function main(opts) { const path = req.originalUrl || req.url; // originalUrl gets lost in koa-connect? if (opts.autoregister && path.match(metricsMatch)) { - return metricsMiddleware(req, res); + return metricsMiddleware(req, res, next); } // bypass() is checked only after /metrics was processed