Skip to content

Commit 058dad7

Browse files
fix(analytics): add error logging, init resilience, JSDoc, and compat test
- Add debug-level logging in analytics middleware catch block for observability without breaking request flow. - Wrap AnalyticsService.init() in try/catch so PostHog failures degrade gracefully instead of crashing app startup. - Add @param and @returns JSDoc to billing.init.js default export. - Add explicit backward-compat test for undefined GDPR flags (captureIp/captureUserAgent) defaulting to capture.
1 parent 0519b4f commit 058dad7

4 files changed

Lines changed: 23 additions & 3 deletions

File tree

lib/middlewares/analytics.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* Module dependencies
33
*/
44
import AnalyticsService from '../services/analytics.js';
5+
import logger from '../services/logger.js';
56

67
/**
78
* Default route prefixes to skip when auto-capturing API request events.
@@ -51,7 +52,9 @@ const createAnalyticsMiddleware = (options = {}) => {
5152
statusCode: res.statusCode,
5253
responseTime: Date.now() - start,
5354
}, groups);
54-
} catch (_) { /* analytics must not break request flow */ }
55+
} catch (err) {
56+
logger.debug('[analytics] finish handler error: %s', err.message);
57+
}
5558
});
5659

5760
return next();

lib/services/express.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,13 @@ const init = async () => {
222222
await initPreParserRoutes(app);
223223
// Initialize analytics (PostHog) and mount auto-capture middleware
224224
// Mounted after pre-parser routes so webhooks are not tracked
225-
await AnalyticsService.init();
226-
app.use(analyticsMiddleware);
225+
// Wrapped in try/catch so analytics failures never prevent app startup
226+
try {
227+
await AnalyticsService.init();
228+
app.use(analyticsMiddleware);
229+
} catch (err) {
230+
logger.warn('[analytics] init failed, running without analytics: %s', err.message);
231+
}
227232
// Initialize Express middleware
228233
initMiddleware(app);
229234
// Initialize Helmet security headers

modules/audit/tests/audit.service.unit.tests.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,13 @@ describe('AuditService unit tests:', () => {
147147
const arg = mockCreate.mock.calls[0][0];
148148
expect(arg.userAgent).toBe('');
149149
});
150+
151+
test('should capture IP and User-Agent when flags are undefined (backward compat)', async () => {
152+
mockConfig.audit = { enabled: true, ttlDays: 90 }; // no captureIp/captureUserAgent
153+
const req = { ip: '10.0.0.1', headers: { 'user-agent': 'Bot/1.0' } };
154+
await AuditService.log({ action: 'test.compat', req });
155+
const arg = mockCreate.mock.calls[0][0];
156+
expect(arg.ip).toBe('10.0.0.1');
157+
expect(arg.userAgent).toBe('Bot/1.0');
158+
});
150159
});

modules/billing/billing.init.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import billingEvents from './lib/events.js';
77
/**
88
* Billing module initialisation.
99
* Wires cross-module integrations that depend on services from lib.
10+
*
11+
* @param {import('express').Application} app - Express application instance
12+
* @returns {Promise<void>}
1013
*/
1114
// eslint-disable-next-line no-unused-vars
1215
export default async (app) => {

0 commit comments

Comments
 (0)