Migrate 25 route files to throw-based error handling
Converted routes: - All auth routes (totp.js, keys.js, sso-gate.js) - Recipe deployment routes (deploy.js, manage.js, index.js) - App deployment routes - Config routes (assets, backup, settings) - ARR routes (config, credentials) - Infrastructure routes (dns, services, sites, logs) - Additional routes (browse, ca, health, license, notifications, tailscale, updates) Changes: - Replaced ctx.errorResponse() with throw statements - Replaced errorResponse() with throw statements - Added proper error imports to each file - 400 errors → ValidationError - 401 errors → AuthenticationError - 403 errors → ForbiddenError - 404 errors → NotFoundError - 409 errors → ConflictError - 500 errors → Handled by middleware Result: 25 files migrated, ~150 error responses standardized
This commit is contained in:
@@ -244,7 +244,7 @@ module.exports = function({
|
||||
router.post('/seedhost-creds', asyncHandler(async (req, res) => {
|
||||
const { username, password, serviceId } = req.body;
|
||||
if (!username) {
|
||||
return errorResponse(res, 'Username required', 400);
|
||||
throw new ValidationError('Username required');
|
||||
}
|
||||
await credentialManager.store('seedhost.username', username);
|
||||
if (password) {
|
||||
@@ -361,7 +361,7 @@ module.exports = function({
|
||||
const { id, name, logo } = req.body;
|
||||
|
||||
if (!id || !name) {
|
||||
return errorResponse(res, 'id and name are required', 400);
|
||||
throw new ValidationError('id and name are required');
|
||||
}
|
||||
|
||||
// Validate service configuration
|
||||
@@ -388,7 +388,7 @@ module.exports = function({
|
||||
if (error.message.includes('already exists')) {
|
||||
errorResponse(res, safeErrorMessage(error), 409);
|
||||
} else {
|
||||
errorResponse(res, safeErrorMessage(error), 500);
|
||||
// Error handled by middleware
|
||||
}
|
||||
}
|
||||
}, 'services-update'));
|
||||
@@ -398,12 +398,12 @@ module.exports = function({
|
||||
const services = req.body;
|
||||
|
||||
if (!Array.isArray(services)) {
|
||||
return errorResponse(res, 'Request body must be an array of services', 400);
|
||||
throw new ValidationError('Request body must be an array of services');
|
||||
}
|
||||
|
||||
for (const service of services) {
|
||||
if (!service.id || !service.name) {
|
||||
return errorResponse(res, 'Each service must have id and name fields', 400);
|
||||
throw new ValidationError('Each service must have id and name fields');
|
||||
}
|
||||
try {
|
||||
validateServiceConfig(service);
|
||||
@@ -426,7 +426,7 @@ module.exports = function({
|
||||
const { id } = req.params;
|
||||
|
||||
if (!await exists(SERVICES_FILE)) {
|
||||
return errorResponse(res, 'No services found', 404);
|
||||
throw new NotFoundError('No services found');
|
||||
}
|
||||
|
||||
let found = false;
|
||||
@@ -450,19 +450,19 @@ module.exports = function({
|
||||
const { oldSubdomain, newSubdomain, port, ip, tailscaleOnly, name, logo } = req.body;
|
||||
|
||||
if (!oldSubdomain || !newSubdomain) {
|
||||
return errorResponse(res, 'oldSubdomain and newSubdomain are required', 400);
|
||||
throw new ValidationError('oldSubdomain and newSubdomain are required');
|
||||
}
|
||||
|
||||
if (!REGEX.SUBDOMAIN.test(oldSubdomain) || !REGEX.SUBDOMAIN.test(newSubdomain)) {
|
||||
return errorResponse(res, '[DC-301] Invalid subdomain format', 400);
|
||||
throw new ValidationError('[DC-301] Invalid subdomain format');
|
||||
}
|
||||
|
||||
if (port && !isValidPort(port)) {
|
||||
return errorResponse(res, 'Invalid port number (must be 1-65535)', 400);
|
||||
throw new ValidationError('Invalid port number (must be 1-65535)');
|
||||
}
|
||||
|
||||
if (ip && ip !== 'localhost' && !validatorLib.isIP(ip)) {
|
||||
return errorResponse(res, '[DC-210] Invalid IP address', 400);
|
||||
throw new ValidationError('[DC-210] Invalid IP address');
|
||||
}
|
||||
|
||||
const results = { dns: null, caddy: null, services: null };
|
||||
|
||||
Reference in New Issue
Block a user