typescript / express промежуточное ПО для обработки ошибок - PullRequest
0 голосов
/ 03 августа 2020

привет, у меня есть промежуточное ПО для обработки ошибок в моем проекте:

  private initializeErrorHandling() {
    this.app.use(
      (err: Error, request: Request, response: Response, _: NextFunction) => {
        if (err instanceof CustomExternalError) {
          return response.status(err.statusCode).json(err.message);
        }

        console.log(err);

        return response.status(500).json({
          status: 'error',
          message: 'Internal server error',
        });
      },
    );
  }

Я использую следующую структуру контроллера:

@singleton()
export class DepartamentController implements IController {
  private router: Router;
  private path: string;
  private services: DepartamentServices;
  constructor() {
    this.path = '/departament';
    this.router = Router();
    this.services = container.resolve(DepartamentServices);
    this.initializeRoutes();
  }
  private initializeRoutes() {
    this.router.post(`${this.path}/create`, this.test.bind(this));
  }
  getPath(): string {
    return this.path;
  }
  getRouter(): Router {
    return this.router;
  }

  private async test() {
    this.services.test();
  }

}

, и это моя роль в моей службе, где я вызвать мою ошибку:

 public async test() {
    throw new CustomExternalError(
      {
        message: 'Validation Failed',
        errors: [
          {
            resource: 'Departament',
            field: 'a',
            code: 'unprocessable',
          },
        ],
      },
      responseCodes.UNPROCESSABLE_ENTITY,
    );
  }

это моя настраиваемая ошибка:

export class CustomExternalError {
  constructor(public error: responseError, public statusCode: responseCodes) {
    this.error;
    this.statusCode;
  }
}

, и я добавляю свои маршруты на свой express сервер с помощью следующей функции:

  private initializeRoutes() {
    container.resolveAll<IController>('Controller').forEach(controller => {
      this.app.use('/', controller.getRouter());
    });
  }

Мой маршрут работает нормально, но по какой-то причине при выдаче ошибки он не вызывает мой дескриптор ошибки промежуточного программного обеспечения, но если я вызываю ошибку на своем контроллере, он работает нормально

Я получил эту ошибку:

(node:8704) UnhandledPromiseRejectionWarning: #<CustomExternalError>
(Use `node --trace-warnings ...` to show where the warning was created)
(node:8704) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:8704) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

1 Ответ

1 голос
/ 03 августа 2020

You test метод является asyn c, поэтому, когда он выбрасывает что-либо, он должен обрабатываться внутри блока catch этого обещания, иначе вы получите предупреждение об отклонении обещания. Итак, вы можете создать промежуточное программное обеспечение, которое перехватывает эти необработанные отклонения обещаний и передает их промежуточному программному обеспечению обработчика ошибок:

Вы можете либо использовать метод оболочки, который обрабатывает это:

const asynchHandler = fn => (...args) => fn(args).catch(args[2])

или этот пакет: express -asyn c -handler .

Затем в вашем контроллере:

  private initializeRoutes() {
    this.router.post(`${this.path}/create`, asynchHandler(this.test.bind(this)));
  }

Или просто обработайте отклонение вашего обещания и явно вызовите midleware

private async test(request: Request, response: Response, next: NextFunction) {
  try {
     ...
     await this.service.test(...)
     ...
   } catch (err: CustomExternalError) {
     next(next)
   }
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...