BitArts Blog

ロードバイク通勤のRubyプログラマで伊豆ダイバー。の個人的なブログ。

500 Internal Server Errorの扱い

500 Internal Server Errorをはじめとする500番台のHTTPステータスコードは、想定外のサーバ内部エラーです。このエラーが出たら、ユーザーがどんな操作が原因だとしてもそれはプログラムのバグです。

リクエストに対してエラーを通知するには400番台を返すべきです。リクエストに対応する結果が無いのなら404 Not Found。受け付けを拒否するなら403 Forbidden。などなど。

Webアプリ脆弱性診断において、500を返すシステムを脆弱性(注意喚起)として報告する場合もあるけど、やや過剰反応かもと思うケースもある。しかし特定の操作をするとサーバーが想定外のエラーを起こしていることをユーザーにお知らせしてしまっていることになるので、望ましいことでないのは確か。(もちろんスタックトレースが出ちゃったりしているのは論外)

だからと言って捕り逃した例外を上位レイヤで全部捕捉して200とかを返せばいいのか?というと、まあ表面的なセキュリティ上はいいかもしれないけど、今度はエラーが起きたことが分かりにくくなって、バグの発見が難しくなってしまいます。結果的に肝心の脆弱性が埋もれたままになってしまうかもしれません。

そこで、例外を全部捕捉してエラーを管理者にメール通知しつつ(もちろんログにも書き出しつつ)、200なり400番台なりを返すのがイイ。

こうしておくと、オープンなサイトだったらリリース後2~3時間もすればGoogleボットが勝手にエラーを洗い出してくれるよ!

しかしリリースしたプログラムがバグバグすぎると無限に大量のメールが飛んでくる場合もあるので、一度捕捉したエラーは無視する処理を入れるなど工夫が必要。Railsだったら「exception_notification」などこのためのプラグインがあるので活用すると良い。しかしもっと強力なのは「Hoptoad」。エラーを通知するだけでなくエラー管理まで提供される高機能なツールです。

このようにエラー通知を仕込むとWebアプリの品質はガンガン高まっていきます。しかしバグがどんどん表面化するので、プログラマにとってはおそらく大幅に仕事が増えるし、緊急性がいちいち(精神的に)高くなる諸刃の剣。