駆け出しのエンジニア日記

プログラミング言語勉強中の奮闘日記

asyncなエラーハンドラ

非同期処理のところでエラーが起きた場合どうなるのでしょうか。

asyncなエラーハンドラについて完成させていきます。

・AppError.js

// extendsキーワードで継承して新しいクラスを作成
class AppError extends Error {
constructor(message, status) {
super();
this.message = message;
this.status = status;
}
}
module.exports = AppError;

・index.js

const express = require('express');
const app = express();
const path = require('path');
const mongoose = require('mongoose');
const methodOverride = require('method-override');
const AppError = require('./AppError');
const Product = require('./models/product');
 
mongoose.connect('mongodb://localhost:27017/farmStand2',
{ useNewUrlParser: true, useUnifiedTopology: true })
.then*1;
}
res.render('products/edit', { product});
});
//エラーハンドラ
app.use((err, req, res, next) => {
const { status = 500, message = '問題が発生しました' } = err;
res.status(status).send(message);
});

第三引数にnextを渡し、next()の中にエラーを入れることで改善されます。

*1:) => {

console.log('MongoDBコネクションOK!!');
})
.catch(err => {
console.log('MongoDBコネクションエラー!!!');
console.log(err);
});
 
app.get('/products/:id', async (req, res) => {
const { id } = req.params;
const product = await Product.findById(id);
if (!product) {
throw new AppError('商品が見つかりません', 404);
}
res.render('products/show', { product });
});
//エラーハンドラ
app.use((err, req, res, next) => {
const { status = 500, message = '問題が発生しました' } = err;
res.status(status).send(message);
});

例えば商品の詳細ページに遷移した際に、存在しないIDでリクエストを投げた場合、

「product」には中身がなくnullになるため、

throw new AppError('商品が見つかりません', 404);」が通り、エラーが返ってくる

想定です。

しかしエラーは起きているのですが、うまくリクエストが投げられていませんでした。

asyncの関数内でエラーが発生した際は、next()関数に渡す必要があります。

問題箇所を修正してみます。

app.get('/products/:id', async (req, res, next) => {
const { id } = req.params;
const product = await Product.findById(id);
if (!product) {
 return next(new AppError('商品が見つかりません', 404