Node-postgresを使用してデータベースにクエリを実行していますが、async/awaitを使用してエラーを正しく処理する方法を知りたいです
私の使用例は、非常に単純なクエリです。
const { Pool } = require('pg');
let config;
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'staging') {
config = { connectionString: process.env.DATABASE_URL, ssl: true };
} else {
config = {
Host: 'localhost',
user: 'myuser',
database: 'mydatabase',
};
}
const pool = new Pool(config);
async function getAllUsers() {
let response;
try {
response = await pool.query('select * FROM users');
} catch (error) {
throw error;
}
return response.rows;
}
それから私のroutes.js
私が持っています
app.get('/all_users', async (req, res) => {
const users = await queries.getAllUsers();
console.log(users); // returns all users fine
});
これはこれまでの私の理解ですが、エラーになるとアプリがフリーズしてUnhandledPromiseRejectionWarning
をスローするため、これに正しくアプローチしているとは思いません。たとえば、間違ったテーブルを提供した場合
async function getAllUsers() {
let response;
try {
response = await pool.query('select * FROM notable');
} catch (error) {
throw error;
}
return response.rows;
}
UnhandledPromiseRejectionWarning: error: relation "notable" does not exist
アプリは30秒後にクラッシュし、このエラーを適切に処理していません
誰かが私がここで欠けているものを指摘できますか?
async
関数またはPromise
がキャッチされないエラーをスローした場合、またはキャッチャーもスローした場合(
throw error;
これは、関数のcallerが、処理するために拒否されたPromiseに直面することを意味します。呼び出し元でawait
を使用している場合は、エラーを適切にキャッチするために、呼び出し元でもtry/catch
を使用する必要があります。
app.get('/all_users', async (req, res) => {
try {
const users = await queries.getAllUsers();
console.log(users);
} catch(e) {
// handle errors
}
});
コンシューマーでtry/catch
を使用せずにエラーを解決する別の方法は、throw
でエラーをcatch
しないことです。
async function getAllUsers() {
let response;
try {
response = await pool.query('select * FROM users');
return response.rows;
} catch (error) {
// handle error
// do not throw anything
}
}
しかし、これにより、消費者がいつエラーが発生したかを知ることが難しくなります。
この特定のケースでは、async
/await
/try
/catch
構造は、IMOに大きなメリットをもたらすことなく、多くの構文ノイズを追加します。代わりにプレーンなPromiseの使用を検討するかもしれません:
const getAllUsers = () => pool.query('select * FROM users')
.then(response => response.rows);
// and:
app.get('/all_users', (req, res) => {
queries.getAllUsers()
.then((users) => {
console.log(users);
})
.catch((err) => {
// handle errors
});
});
async
とawait
は、コードでよりフラットに見せたい.then
がいくつかある場合に光ります。 .then
が1つしかない場合、IMOをasync
/await
構文に変換してもあまりメリットはありません。もちろん、それはあなた次第です。