refactor(routes/user): replace errorFormatter with ApiError/ValidationError throws

This commit is contained in:
null 2026-07-10 17:52:32 -05:00
parent a325c94dd4
commit e9f52b7472
1 changed files with 15 additions and 26 deletions

View File

@ -8,7 +8,16 @@ const { getDb } = require('../db/database.cts');
const { seedDemoData } = require('../scripts/seedDemoData.cts'); const { seedDemoData } = require('../scripts/seedDemoData.cts');
const { demoDataLimiter } = require('../middleware/rateLimiter.cts'); const { demoDataLimiter } = require('../middleware/rateLimiter.cts');
const { eraseUserData, clearSeededDemoData } = require('../services/userDataService.cts'); const { eraseUserData, clearSeededDemoData } = require('../services/userDataService.cts');
const { standardizeError } = require('../middleware/errorFormatter.cts'); const { ApiError, ValidationError } = require('../utils/apiError.cts');
// 4xx service errors keep their message/code on the wire; anything else is
// rethrown raw so the terminal handler masks + logs it as a 5xx.
function toUserOpError(err, fallbackCode) {
if (err.status && err.status < 500) {
return new ApiError(err.code || fallbackCode, err.message, err.status);
}
return err;
}
// GET /api/user/seeded-status — whether the current user has demo data, with counts // GET /api/user/seeded-status — whether the current user has demo data, with counts
router.get('/seeded-status', (req: Req, res: Res) => { router.get('/seeded-status', (req: Req, res: Res) => {
@ -39,14 +48,7 @@ router.get('/seeded-status', (req: Req, res: Res) => {
seededTransactions, seededTransactions,
}); });
} catch (err) { } catch (err) {
res throw toUserOpError(err, 'SEEDED_STATUS_ERROR');
.status(err.status || 500)
.json(
standardizeError(
err.message || 'Seeded status check failed',
err.code || 'SEEDED_STATUS_ERROR',
),
);
} }
}); });
@ -66,14 +68,7 @@ router.post('/clear-demo-data', demoDataLimiter, (req: Req, res: Res) => {
counts: result.counts, counts: result.counts,
}); });
} catch (err) { } catch (err) {
res throw toUserOpError(err, 'CLEAR_DEMO_ERROR');
.status(err.status || 500)
.json(
standardizeError(
err.message || 'Clear demo data operation failed',
err.code || 'CLEAR_DEMO_ERROR',
),
);
} }
}); });
@ -102,9 +97,7 @@ router.post('/seed-demo-data', demoDataLimiter, (req: Req, res: Res) => {
counts: result.counts, counts: result.counts,
}); });
} catch (err) { } catch (err) {
res throw toUserOpError(err, 'SEED_ERROR');
.status(err.status || 500)
.json(standardizeError(err.message || 'Seed operation failed', err.code || 'SEED_ERROR'));
} }
}); });
@ -116,17 +109,13 @@ router.post('/erase-data', demoDataLimiter, (req: Req, res: Res) => {
.trim() .trim()
.toUpperCase(); .toUpperCase();
if (confirm !== 'ERASE') { if (confirm !== 'ERASE') {
return res throw ValidationError('Type ERASE to confirm.', 'confirm', 'ERASE_CONFIRM_REQUIRED');
.status(400)
.json(standardizeError('Type ERASE to confirm.', 'ERASE_CONFIRM_REQUIRED', 'confirm'));
} }
try { try {
const result = eraseUserData(getDb(), req.user.id); const result = eraseUserData(getDb(), req.user.id);
res.json({ success: true, ...result }); res.json({ success: true, ...result });
} catch (err) { } catch (err) {
res throw toUserOpError(err, 'ERASE_ERROR');
.status(err.status || 500)
.json(standardizeError(err.message || 'Failed to erase data', err.code || 'ERASE_ERROR'));
} }
}); });