refactor(routes): analytics + tracker → throw pattern (batch 1)
Drop try/catch swallows + standardizeError; throw ValidationError/ApiError (tracker preserves result.status via ApiError). Test harness updated to simulate the terminal handler. 236/236. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
26d976e272
commit
59c2917e1d
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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}');
|
||||
|
|
|
|||
Loading…
Reference in New Issue