diff --git a/routes/analytics.cts b/routes/analytics.cts index 695b4ed..075eb9d 100644 --- a/routes/analytics.cts +++ b/routes/analytics.cts @@ -2,13 +2,12 @@ import type { Req, Res, Next } from '../types/http'; const express = require('express'); const router = express.Router(); -const { standardizeError } = require('../middleware/errorFormatter.cts'); +const { ValidationError } = require('../utils/apiError.cts'); const { getAnalyticsSummary } = require('../services/analyticsService.cts'); router.get('/summary', (req: Req, res: Res) => { const result = getAnalyticsSummary(req.user.id, req.query); - if (result.error) - return res.status(400).json(standardizeError(result.error, 'VALIDATION_ERROR', 'month')); + if (result.error) throw ValidationError(result.error, 'month'); res.json(result); }); diff --git a/routes/tracker.cts b/routes/tracker.cts index 2513d60..2f6a8d6 100644 --- a/routes/tracker.cts +++ b/routes/tracker.cts @@ -3,42 +3,23 @@ import type { Req, Res, Next } from '../types/http'; const express = require('express'); const router = express.Router(); const { getTracker, getUpcomingBills, getOverdueCount } = require('../services/trackerService.cts'); -const { standardizeError } = require('../middleware/errorFormatter.cts'); +const { ApiError, ValidationError } = require('../utils/apiError.cts'); // GET /api/tracker/overdue-count — lightweight count for sidebar badge router.get('/overdue-count', (req: Req, res: Res) => { - try { - res.json(getOverdueCount(req.user.id)); - } catch (err) { - console.error('[tracker/overdue-count]', err.message); - res.status(500).json(standardizeError('Failed to load overdue count', 'INTERNAL_ERROR')); - } + res.json(getOverdueCount(req.user.id)); }); // GET /api/tracker?year=2026&month=5 router.get('/', (req: Req, res: Res) => { - try { - const result = getTracker(req.user.id, req.query); - if (result.error) { - return res - .status(result.status || 400) - .json(standardizeError(result.error, 'VALIDATION_ERROR')); - } - res.json(result); - } catch (err) { - console.error('[tracker]', err.message); - res.status(500).json(standardizeError('Failed to load tracker data', 'INTERNAL_ERROR')); - } + const result = getTracker(req.user.id, req.query); + if (result.error) throw new ApiError('VALIDATION_ERROR', result.error, result.status || 400); + res.json(result); }); // GET /api/tracker/upcoming?days=30 router.get('/upcoming', (req: Req, res: Res) => { - try { - res.json(getUpcomingBills(req.user.id, req.query)); - } catch (err) { - console.error('[tracker/upcoming]', err.message); - res.status(500).json(standardizeError('Failed to load upcoming bills', 'INTERNAL_ERROR')); - } + res.json(getUpcomingBills(req.user.id, req.query)); }); module.exports = router; diff --git a/tests/trackerService.test.js b/tests/trackerService.test.js index b8cb16a..b964eeb 100644 --- a/tests/trackerService.test.js +++ b/tests/trackerService.test.js @@ -164,7 +164,15 @@ test('GET /tracker returns a standardized error for an invalid month', async () resolve({ status: this.statusCode, data: d }); }, }; - handler(req, res); + // Handlers now throw ApiError; simulate the terminal error handler. + try { + handler(req, res); + } catch (err) { + resolve({ + status: err.status || 500, + data: { error: err.code, message: err.message, code: err.code, field: err.field ?? null }, + }); + } }); assert.equal(result.status, 400); assert.equal(result.data.code, 'VALIDATION_ERROR', 'standardized shape, not a plain {error}');