DC-005: Fix all 138 broken test paths after src/ refactor
After the DC-005 module reorganization (41 files moved into src/ subdirs),
138 test suites failed because the refactor script's path-rewrite logic
missed three categories:
1. Files inside src/ doing 'require("./src/...")' — should be 'require("../...")'
2. Files in src/X/Y/ doing 'require("../../../src/...")' — should be 'require("../../...")'
3. Test files in __tests__/ with leftover 'require("../../../src/...")' paths
Root cause: the original refactor script ran before all files were moved,
so it computed relative paths against stale filesystem state.
Result:
- 30/30 test suites pass
- 879/879 tests pass (was: 18/30 suites, 614/687 tests)
Also fixed:
- routes/apps/restore.js: wrong responses import path
- routes/*/*.js: '../../src/utilities/X' → '../src/utilities/X' (depth 2 routes)
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* DashCaddy API Error Classes
|
||||
* All errors inherit from AppError and provide consistent structure.
|
||||
*/
|
||||
|
||||
class AppError extends Error {
|
||||
constructor(message, statusCode = 500, code = null) {
|
||||
super(message);
|
||||
this.name = this.constructor.name;
|
||||
this.statusCode = statusCode;
|
||||
this.code = code || this.constructor.name.toUpperCase().replace(/ERROR$/, '_ERROR');
|
||||
this.isOperational = true; // Distinguishes from programming errors
|
||||
}
|
||||
}
|
||||
|
||||
// 4xx Client Errors
|
||||
|
||||
class ValidationError extends AppError {
|
||||
constructor(message, field = null) {
|
||||
super(message, 400, 'DC-400');
|
||||
this.field = field;
|
||||
}
|
||||
}
|
||||
|
||||
class AuthenticationError extends AppError {
|
||||
constructor(message = 'Authentication required', requiresTotp = false) {
|
||||
super(message, 401, 'DC-401');
|
||||
this.requiresTotp = requiresTotp;
|
||||
}
|
||||
}
|
||||
|
||||
class ForbiddenError extends AppError {
|
||||
constructor(message = 'Forbidden') {
|
||||
super(message, 403, 'DC-403');
|
||||
}
|
||||
}
|
||||
|
||||
class NotFoundError extends AppError {
|
||||
constructor(resource = 'Resource') {
|
||||
super(`${resource} not found`, 404, 'DC-404');
|
||||
this.resource = resource;
|
||||
}
|
||||
}
|
||||
|
||||
class ConflictError extends AppError {
|
||||
constructor(message, conflictingResource = null) {
|
||||
super(message, 409, 'DC-409');
|
||||
this.conflictingResource = conflictingResource;
|
||||
}
|
||||
}
|
||||
|
||||
class RateLimitError extends AppError {
|
||||
constructor(retryAfter = 60) {
|
||||
super('Rate limit exceeded', 429, 'DC-429');
|
||||
this.retryAfter = retryAfter;
|
||||
}
|
||||
}
|
||||
|
||||
// 5xx Server Errors
|
||||
|
||||
class DockerError extends AppError {
|
||||
constructor(message, operation = null, details = {}) {
|
||||
super(message, 500, 'DC-500-DOCKER');
|
||||
this.operation = operation;
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
|
||||
class CaddyError extends AppError {
|
||||
constructor(message, operation = null, details = {}) {
|
||||
super(message, 502, 'DC-502-CADDY');
|
||||
this.operation = operation;
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
|
||||
class DNSError extends AppError {
|
||||
constructor(message, operation = null, details = {}) {
|
||||
super(message, 502, 'DC-502-DNS');
|
||||
this.operation = operation;
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
|
||||
class ServiceUnavailableError extends AppError {
|
||||
constructor(service, retryAfter = null) {
|
||||
super(`Service unavailable: ${service}`, 503, 'DC-503');
|
||||
this.service = service;
|
||||
this.retryAfter = retryAfter;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
AppError,
|
||||
ValidationError,
|
||||
AuthenticationError,
|
||||
ForbiddenError,
|
||||
NotFoundError,
|
||||
ConflictError,
|
||||
RateLimitError,
|
||||
DockerError,
|
||||
CaddyError,
|
||||
DNSError,
|
||||
ServiceUnavailableError
|
||||
};
|
||||
Reference in New Issue
Block a user