diff --git a/index.js b/index.js index d37eb9d..2c1fb8c 100644 --- a/index.js +++ b/index.js @@ -80,7 +80,10 @@ module.exports = (registry, config = {}) => { if (ignoreRoute(request, server)) return - const { summaryTimer, histogramTimer } = timers.get(request) + const requestTimers = timers.get(request) + if (!requestTimers) return + + const { summaryTimer, histogramTimer } = requestTimers timers.delete(request) if (ignore(request, response, server)) return diff --git a/test/helper.js b/test/helper.js index dae99cc..80c9adf 100644 --- a/test/helper.js +++ b/test/helper.js @@ -15,6 +15,9 @@ function createHttpServer (t) { if (req.url === '/2s') { await sleep(2000) } + if (req.url === '/10s') { + await sleep(10000) + } res.end('Hello World\n') } ) diff --git a/test/http-metrics.test.js b/test/http-metrics.test.js index 0052ca1..5afce52 100644 --- a/test/http-metrics.test.js +++ b/test/http-metrics.test.js @@ -2,6 +2,7 @@ const assert = require('node:assert/strict') const { test } = require('node:test') +const { setTimeout: sleep } = require('node:timers/promises') const { request } = require('undici') const { Registry } = require('prom-client') const httpMetrics = require('../index.js') @@ -258,3 +259,32 @@ test('should ignore route with a callback', async (t) => { } } }) + +test('should not throw if request timers are not found', async (t) => { + const serverUrl = createHttpServer(t) + + const responsePromise = request(serverUrl + '/10s', { + method: 'GET', + headers: { 'x-ignore': 'true' }, + }) + + // Wait for server to receive the request + await sleep(500) + + const registry = new Registry() + httpMetrics(registry, { + ignore: (req) => req.headers['x-ignore'] === 'true', + }) + + await responsePromise + + const metrics = await registry.getMetricsAsJSON() + assert.strictEqual(metrics.length, 2) + + const histogramMetric = metrics.find( + (metric) => metric.name === 'http_request_duration_seconds' + ) + + const histogramValues = histogramMetric.values + assert.strictEqual(histogramValues.length, 0) +})