-
-
Notifications
You must be signed in to change notification settings - Fork 318
Open
Description
Current API middleware implementations have very low test coverage and contain tightly coupled logic that makes testing, debugging, and maintenance difficult. In particular, validation and error handling paths include complex async flows, repeated schema compilation, and limited observability during request processing.
Proposed Changes
- Validator Caching (Performance Improvement)
Avoid recompiling AJV validators for every request.
class ValidatorCache {
private cache = new Map();
async getValidator(path, method) {
const key = `${path}:${method}`;
if (!this.cache.has(key)) {
this.cache.set(key, await this.compileValidator(path, method));
}
return this.cache.get(key);
}
}
- Simplified Validation Middleware Flow :
async function validationMiddleware(options) {
return async (req, res, next) => {
try {
sanitizeInput(req.body);
const validate =
await validatorCache.getValidator(options.path, options.method);
if (!validate(req.body)) {
throw new ProblemException({ status: 422 });
}
await validateDocuments(req, options);
next();
} catch (err) {
next(err);
}
};
}
- Problem Middleware Error Handling
Helper utilities
function extractErrorType(type: string): string {
return type.replace('https://api.asyncapi.com/problem/', '');
}
function categorizeError(status: number): 'client' | 'server' {
return status >= 500 ? 'server' : 'client';
}
So the simplified middleware flow:
function problemMiddleware(error, req, res, next) {
if (res.headersSent) {
return next(error);
}
try {
const problemShape = error.get();
const status = problemShape.status || 500;
problemShape.status = status;
problemShape.title ||= 'Internal server error';
const errorType = extractErrorType(problemShape.type);
const category = categorizeError(status);
logger.error(
`[${req.method}] ${req.path} >> Status:: ${status}, Type:: ${errorType}`,
{ category }
);
const problem = error.toObject({
includeStack: status >= 500,
includeCause: status >= 500,
});
res.status(status).json(problem);
} catch (err) {
next(err);
}
}
Steps to Reproduce:
npx nyc npm testnpx nyc report --reporter=htmlstart coverage/index.html- Navigate to
problem.middleware.js,validation.middleware.js
Happy to raise a PR for this if the maintainers approve
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Status
To Triage