UnhandledPromiseRejectionWarning в приложении Express - PullRequest
0 голосов
/ 18 сентября 2018

В настоящее время я изучаю стек Javascript / Node.js / MEAN и следую учебному пособию по Express.

Я получаю следующую ошибку:

(узел: 11524) UnhandledPromiseRejectionWarning: необработанное отклонение обещания (идентификатор отклонения: 1): TypeError: Невозможно прочитать свойство close из undefined (узел): 11524) [DEP0018] Предупреждение об устаревании: отклонение необработанного обещания устарело.В будущем отклонения обещаний, которые не обрабатываются, завершат процесс Node.js с ненулевым кодом выхода.

Когда я попаду по этому маршруту в своем браузере.

function router(nav) {
adminRouter.route('/')
    .get((req, res) => {
        const url = 'mongodb://localhost:27017';
        const dbName = 'libraryApp';

        (async function mongo() {
            let client;
            try {
                client = await mongoClient.connect(url);
                debug('Connected correctly to server');

                const db = client.db(dbName);

                const response = await db.collection('books').insertMany(books);
                res.json(response);
            } catch (err) {
                debug(err.stack);
            }
            client.close();
        }());
    });

return adminRouter;

}

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

1 Ответ

0 голосов
/ 18 сентября 2018

Если эта строка отклоняет:

 client = await mongoClient.connect(url);

Затем вы переходите к блоку catch и после этого блока перехвата вызываете client.close().Но client - это undefined, поэтому client.close() бросит, и вы не находитесь внутри try/catch в этот момент.Поскольку вы находитесь внутри функции async, этот бросок превратится в отклоненное обещание, с которым у вас нет .catch() обработки.Таким образом, вы получите необработанное отклонение обещания.

Вы сможете исправить это следующим образом:

function router(nav) {
    adminRouter.route('/').get(async (req, res) => {
        const url = 'mongodb://localhost:27017';
        const dbName = 'libraryApp';

        let client;
        try {
            client = await mongoClient.connect(url);
            debug('Connected correctly to server');

            const db = client.db(dbName);

            const response = await db.collection('books').insertMany(books);
            res.json(response);
        } catch (err) {
            debug(err.stack);
            // make sure and send some response on errors
            res.sendStatus(500);
        }
        if (client) {
            client.close();
        }
    });
    return adminRouter;
}

Это вносит несколько изменений:

  1. Добавьте if (client) перед вызовом client.close(), чтобы защитить его от случая, когда `клиент никогда не был установлен.
  2. Сделайте весь .get() обратный вызов равным async вместо использования IIFE (не требуется, просто кажетсячище мне)
  3. Отправьте сообщение об ошибке и ответ в своем заявлении catch, чтобы вы всегда отправляли какой-либо http-ответ, даже в ситуациях с ошибкой.

Если вы действительно хотите быть отказоустойчивым, вы можете просто добавить еще одну попытку / поймать:

function router(nav) {
    adminRouter.route('/').get(async (req, res) => {
        const url = 'mongodb://localhost:27017';
        const dbName = 'libraryApp';

        let client;
        try {
            client = await mongoClient.connect(url);
            debug('Connected correctly to server');

            const db = client.db(dbName);

            const response = await db.collection('books').insertMany(books);
            res.json(response);
        } catch (err) {
            debug(err.stack);
            // make sure and send some response on errors
            res.sendStatus(500);
        }
        try {
            if (client) {
                client.close();
            }
        } catch(e) {
            console.log("unable to close database connection");
        }
    });
    return adminRouter;
}
...