引き続き、ドットインストールのExpress入門 をやっています。
サンプルはExpress3系ですが、Express4系でチャレンジしています。今回は最後の #21 エラー処理をしていこう 値が正しくない時などエラーページを表示させる方法のレッスンでハマりました。
サンプルでは、app.use(app.router);
の下、Routingの上に、エラーハンドリングを行う下記の処理を記述するようにあります。app.useだからエラーハンドリングもミドルウェアって認識で良いのでしょうかね?
// error app.use(function(err, req, res, next) { res.send(err.message); });
Express 4.xではapp.routerは廃止されているので、Routingの上、色いろあるミドルウェアの最後に同じコードを追加しました。
// app.js var express = require('express'), logger = require('morgan'), bodyParser = require('body-parser'), connect = require('connect'), methodOverride = require('method-override'), expressSession = require('express-session'), cookieParser = require('cookie-parser'), csrf = require('csurf'), app = express(), post = require('./routes/post'); app.set('views', __dirname + '/views'); app.set('view engine', 'ejs'); // middleware app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); app.use(methodOverride(function(req, res){ if (req.body && typeof req.body === 'object' && '_method' in req.body) { // look in urlencoded POST bodies and delete it var method = req.body._method; delete req.body._method; return method; } })); // csrf対策 app.use(cookieParser()); app.use(expressSession({secret: 'secret_key'})); app.use(csrf()); app.use(function(req, res, next) { var token = req.csrfToken(); res.locals.csrftoken = token; next(); }); // error app.use(function(err, req, res, next) { res.send(err.message); }); // Routing app.get('/', post.index); app.get('/posts/:id([0-9]+)', post.show); app.get('/posts/new', post.new); app.post('/posts/create', post.create); app.get('/posts/:id([0-9]+)/edit', post.edit); app.put('/posts/:id([0-9]+)', post.update); app.delete('/posts/:id([0-9]+)', post.destroy); app.listen(3000);
サンプルのとおりだど、next( new Error('Error Message') )
で渡されたエラーメッセージだけが表示されるはずなのですが、、、
Error: ID not valid at exports.update (/express/blog/routes/post.js:25:15) at Layer.handle [as handle_request] (/express/blog/node_modules/express/lib/router/layer.js:95:5) at next (/express/blog/node_modules/express/lib/router/route.js:131:13) at Route.dispatch (/express/blog/node_modules/express/lib/router/route.js:112:3) at Layer.handle [as handle_request] (/express/blog/node_modules/express/lib/router/layer.js:95:5) at /express/blog/node_modules/express/lib/router/index.js:277:22 at param (/express/blog/node_modules/express/lib/router/index.js:349:14) at param (/express/blog/node_modules/express/lib/router/index.js:365:14) at Function.process_params (/express/blog/node_modules/express/lib/router/index.js:410:3) at next (/express/blog/node_modules/express/lib/router/index.js:271:10)
はい。エラーがそのまま表示されちゃっています。
methodOverrideとcsrf対策の処理もExpress 4.xに合わせるために変更しているので、これらの影響があるのかもと思い、書く処理にconsole.log
を仕込んでみました。その結果
GET /posts/2/edit 200 6.993 ms - 604 >> methodOverride >> csrftoken >> next( new Error('ID not valid') ) Error: ID not valid
と表示されましたので、methodOverrideとcsrf対策の処理は問題なく行われており、next( new Error() )
がエラーハンドリングの処理に行かずにエラーになっていると解りました。
エラーハンドリングの処理を書く位置が悪かった。
色々と検索してみたのですが、コレといった解決策を見つけることができず、express
コマンドで自動生成できるapp.js
を参考に見てみることにしました。どうやらRoutingの指定より後にエラーハンドリングを書いてるっぽい!
ということで、エラーハンドリングの記述をRoutingより後に移動させてみました。
// app.js var express = require('express'), logger = require('morgan'), bodyParser = require('body-parser'), connect = require('connect'), methodOverride = require('method-override'), expressSession = require('express-session'), cookieParser = require('cookie-parser'), csrf = require('csurf'), app = express(), post = require('./routes/post'); app.set('views', __dirname + '/views'); app.set('view engine', 'ejs'); // middleware app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); app.use(methodOverride(function(req, res){ if (req.body && typeof req.body === 'object' && '_method' in req.body) { // look in urlencoded POST bodies and delete it var method = req.body._method; delete req.body._method; return method; } })); // csrf対策 app.use(cookieParser()); app.use(expressSession({secret: 'secret_key'})); app.use(csrf()); app.use(function(req, res, next) { var token = req.csrfToken(); res.locals.csrftoken = token; next(); }); // Routing app.get('/', post.index); app.get('/posts/:id([0-9]+)', post.show); app.get('/posts/new', post.new); app.post('/posts/create', post.create); app.get('/posts/:id([0-9]+)/edit', post.edit); app.put('/posts/:id([0-9]+)', post.update); app.delete('/posts/:id([0-9]+)', post.destroy); // error app.use(function(err, req, res, next) { res.send(err.message); }); app.listen(3000);
これで、試してみたところ意図したとおりに画面にはエラーメッセージだけが表示されるようになりました。
https://dotinstall.com/lessons/basic_expressjs

- 作者: 山田胡瓜
- 発売日: 2015/09/06
- メディア: Kindle版
- この商品を含むブログ (5件) を見る