Skip to content

[TEST] : low coverage in lib/apps/api/middlewares #2019

@Ishita-190

Description

@Ishita-190

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.

Image

Proposed Changes

  1. 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);
  }
}
  1. 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);
    }
  };
}
  1. 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 test
  • npx nyc report --reporter=html
  • start coverage/index.html
  • Navigate to problem.middleware.js, validation.middleware.js

Happy to raise a PR for this if the maintainers approve

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    To Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions