Правильный способ выяснить, какое отклонение было у обещания? - PullRequest
1 голос
/ 27 марта 2019

У меня есть API / экспресс-маршрутизатор:

router.post("/signup", async function (req, res) {
    try {
        var user = await controllers.user.register(req.body.username, req.body.password);
        req.session.user = user;
        res.json(user);
    } catch (e) {
        res.status(500).json("DB Error");
    }
});

В настоящее время при ошибке возвращается ошибка 500 БД.Это мой контроллер:

function register(username, password) {
    return new Promise((resolve, reject) => {
        User.findOne({ username: username }).lean().exec((e, doc) => {
            if (e) reject(e);
            if (doc) {
                reject("Username already exists.");
            } else {
                var user = new User({ username, password: hash(password) });
                user.save((e) => {
                    if (e) reject(e);
                    else {
                        delete user.password;
                        resolve(user);
                    }
                });
            }
        });

    });
}

Как правильно вернуть 400, если имя пользователя уже существует, и 500, если это ошибка базы данных?

Ответы [ 2 ]

2 голосов
/ 27 марта 2019

Mongoose уже использует обещания, использование new Promise является антипаттерном построения обещаний.

В Express нет концепции контроллеров, есть только обработчики маршрутов и промежуточное ПО. Так как register должен быть очень осведомлен о том, как он будет использоваться в ответе, может не потребоваться другой уровень абстракции над обработчиком маршрута. Не будет проблем, когда функция имеет доступ к параметрам обработчика и может сформировать ответ на месте.

Это может быть:

router.post("/signup", async function (req, res) {
    try {
        const { body, password } = req.body;
        const user = await User.findOne({ username: username }).lean();
        if (user) {
          res.status(400).json("Username already exists");
        } else {
          ...
          res.json(user);
        }
    } catch (e) {
        res.status(500).json("DB Error");
    }
});

В случае необходимости повторного использования обработчика маршрута в нескольких местах с некоторыми вариациями, он может быть реорганизован в функцию более высокого порядка или другого помощника, который знает об исходных параметрах req и res.

1 голос
/ 27 марта 2019

Вы можете изменить способ отказа от Обещания. Я бы предложил что-то вроде:

function register(username, password) {
    return new Promise((resolve, reject) => {
        User.findOne({ username: username }).lean().exec((e, doc) => {
            if (e) reject(500);
            if (doc) {
                reject(400);
            } else {
                var user = new User({ username, password: hash(password) });
                user.save((e) => {
                    if (e) reject(500);
                    else {
                        delete user.password;
                        resolve(user);
                    }
                });
            }
        });

    });
}

А в маршруте:

router.post("/signup", async function (req, res) {
    try {
        var user = await controllers.user.register(req.body.username, req.body.password);
        req.session.user = user;
        res.json(user);
    } catch (e) {
        res.status(e).json(e == 400 ? "Username already exists." : "DB Error");
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...