0

node.js Web アプリケーションを作成しました。現在、DBにMSSQLを使用しています。node-mssqlパッケージを追加しました。対応する SQL 関数を実行する関数をsql.jsという別のファイルに作成しました。controller.jsはawait キーワードでそれらを呼び出します。一度に 1 つのリクエストを行ったときはエラーはありませんでしたが、2 つのリクエストがほぼ同時に来ると、次のエラーが発生します。

(ノード:136648) UnhandledPromiseRejectionWarning: 未処理の約束の拒否 (拒否 ID: 1): ReferenceError: エラーが定義されていません
(ノード:136648) [DEP0018] DeprecationWarning: 未処理の約束の拒否は非推奨です。今後、処理されないプロミスの拒否は、ゼロ以外の終了コードで Node.js プロセスを終了します。

私は接続に関係があると思います.グローバル接続を使用していますが、controller.jsをデバッグし、プールが定義されていることを確認したので、問題の原因がわかりません.

SQL.js

const sql = require('mssql'); 
const config = {
    user: 'admin',
    password: 'linux',
    server: '11.222.33.44',
    database: 'master'
}
const pool = new sql.ConnectionPool(config); 
pool.on('error', err => {
    if (err) {
        console.log('sql errors', err);
    }
    if (!err) {
        pool.connect();
    }
});
module.exports.getUsers = async() => {
    // const pool = await sql.connect(config);
    try{
        const result  = await pool.request()
            .query(`SELECT * FROM master.dbo.users ORDER BY user_id`)
        // sql.close();
        return result.recordset; 
    }catch(err){
        throw error; 
    }
}
module.exports.getProducts = async() => {
    // const pool = await sql.connect(config);
    try{
        const result  = await pool.request()
            .query(`SELECT * FROM master.dbo.products ORDER BY product_zip`)
        // sql.close();
        return result.recordset; 
    }catch(err){
        throw error; 
    }
}

controller.js

const express = require('express');
const {getInfo, getUsers, getProducts} = require('../lib/sql');
const router = express.Router();

...

/// Get Users
router.get('/controller/getUsers', async(req, res, next) => {
    console.log('get: /controller/getUsers'); 
    const users = await getUsers(); 
    res.status(200).json(users);   
});
/// Get Products
router.get('/controller/getProducts', async(req, res, next) => {
    console.log('get: /controller/getProducts'); 
    const products = await getProducts(); 
    res.status(200).json(products);
});
module.exports = router;
4

1 に答える 1

4

さまざまなrouter.getコールバックにエラー処理はなく、渡した関数の戻り値router.getには何もしません。そのため、関数を渡すと、関数が返す promise は処理されず、拒否された promise については、これは未処理のエラーです。したがって、エラーメッセージ。async

代わりに: エラーを処理する必要があります。例えば:

router.get('/controller/getUsers', async(req, res, next) => {
    try {
        console.log('get: /controller/getUsers'); 
        const users = await getUsers(); 
        res.status(200).json(templates);
    } catch (e) {
        res.status(500).send(/*...*/);
    }
});

それでも処理されない promise を返しますが、少なくとも拒否することはありません(コードで何も失敗しないと仮定しcatchます)。

エラーを返す一般的な方法がある場合router.getは、コールバックからのエラーを処理するラッパー関数 (など) を自分自身に提供して、適切に一元化することをお勧めします。

例えば:

const asyncRouterGet = (route, handler) => {
    return router.get(route, (req, res, next) => {
        handler(req, res, next)
        .catch(err => {
            // Common error handling here
            res.status(500).send(/*...*/);
        });
    });
};

それから

asyncRouterGet('/controller/getUsers', async(req, res, next) => {
    console.log('get: /controller/getUsers'); 
    const users = await getUsers(); 
    res.status(200).json(templates);
});

asyncRouterGet...拒否はの生成されたコールバックによって自動的に処理されることがわかっているためです。


そして明らかに、これをしないでください:

try {
    // ...
}
catch (err) {
    throw error;
}

error引用されたコードのどこにも定義されていません。

try {
    // ...
}
catch (err) {
    throw err;
}

無意味です。他に何もせずに再スローする場合は、try/をオフのままにしてください。catch

于 2018-02-13T15:40:37.063 に答える