Почему мой обработчик ошибок в ExpressJS не работает? - PullRequest
0 голосов
/ 21 марта 2020

Я создаю API с ExpressJS для моего проекта и хотел бы реализовать обработку ошибок. Я прочитал несколько статей на inte rnet о том, как это сделать, и попробовал несколько способов реализации обработки ошибок в моем API. У меня сейчас проблема в том, что мой обработчик ошибок не работает, и я понятия не имею, почему. Чтобы сделать мою проблему более понятной, вот что я уже попробовал:

Это нижняя часть моего индекса. js file:

// Controllers
app.use("/auth", require("./controllers/auth"));
app.use("/clients", require("./controllers/clients"));

// Error handling
app.use((err, req, res, next) => {
    logger.error(
        `date - ${new Date()}, message - ${err.message}, stack trace - ${
            err.stack
        }`
    );

    return res
        .status(500)
        .json({ status: 500, message: "Something went wrong." });
});

const PORT = process.env.PORT || 3001;
app.listen(3001, () => {
    console.log(`Listening on port ${PORT}`);
});

В качестве примечания: я использую Winston JS для регистрации ошибок в файлах и Mon goose в качестве ORM для моей базы данных MongoDB.

Это контроллер для маршрута клиента (контроллеры / клиенты. js):

const express = require("express");
const router = express.Router();

const ClientsService = require("../services/clients");

// GET -> Get all clients -> /clients
router.get("/", async (req, res) => {
    const clients = await ClientsService.getAll();

    return res.status(200).json({ status: 200, data: clients });
});

module.exports = router;

И, наконец, это служба поддержки клиентов (услуги / клиенты. js), место, где я хотел бы выдавать ошибки (возможно, это не то место, где можно выдавать ошибки, пожалуйста, исправьте меня, если я Я ошибаюсь):

const ClientModel = require("../models/Client");

const getAll = async () => {
    return ClientModel.findById({})
        .then(clients => clients)
        .catch(err => {
            throw new Error(err);
        });
};

module.exports = { getAll };

Как видите, я поместил пустой объект в функцию для findById. Это должно вызвать ошибку, чтобы я мог проверить обработку ошибок. Несколько строк ниже, я выкидываю ошибку. Я ожидаю, что это вызовет функцию промежуточного программного обеспечения, которую я определил в index. js. Эта функция промежуточного программного обеспечения, как показано в коде для индекса. js, записывает ошибку в файл и затем отправляет клиенту ответ 500 (читай 'user').

Вместо этого я на самом деле получить ошибку в консоли под названием «UnhandledPromiseRejectionWarning». Вот ошибка:

(node:15416) UnhandledPromiseRejectionWarning: Error: CastError: Cast to ObjectId failed for value "{}" at path "_id" for model "clients"
    at D:\projects\myproject\services\clients.js:7:10
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async D:\projects\myproject\controllers\clients.js:8:18
(node:15416) 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:15416) [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.

Почему моя обработка ошибок не работает? Если у вас есть решение, как я могу включить обработку ошибок для моего кода?

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 21 марта 2020

В документации express об обработке ошибок написано:

Необходимо отловить ошибки, возникающие в асинхронном коде, вызываемом обработчиками маршрутов или промежуточным программным обеспечением, и передать их Express для обработки.

Таким образом, вам нужно перехватить ошибку и передать ее промежуточному программному обеспечению express, используя next(err):

Таким образом, ваш контроллер необходимо обновить как это:

router.get("/", async (req, res, next) => {
  try {
    const clients = await ClientsService.getAll();
    return res.status(200).json({ status: 200, data: clients });
  } catch (err) {
    next(err);
  }
});

Также вам лучше вернуть обещание от вашего сервиса, как это, что более понятно:

const getAll = () => {
  return ClientModel.findById({});
};

Теперь, если вы хотите использовать try catch на каждом маршруте , вы можете проверить этот ответ, чтобы избежать этого.

1 голос
/ 21 марта 2020

Сделайте попытку / поймайте перед вызовом функции asyn c

try{
    const clients = await ClientsService.getAll();
    return res.status(200).json({ status: 200, data: clients });
}catch(err){
    return res.status(500).json({ status: 500, message: 'There was a problem :' + err });
}
...