railsでAPIを作る時など、サーバエラーが起こっても、レスポンスが常に同じフォーマットのjsonなどであってほしかったりします。
例えば、成功時は以下のようなレスポンスになり、
{
"status": "ok",
"code": 200,
"content": {
"id": 1
}
}
失敗時は以下のようなレスポンスになるパターンの場合。
{
"status": "ng",
"code": 500,
"content": {
"message": "エラーだよ"
}
}
デフォルトだとサーバエラーが起こるとhtmlで出力されてしまいます。
こういう時も常にjsonで出力するためには、ApplicationControllerに以下の記述をします。
app/controllers/application_controller.rb
rescue_from StandardError, :with => :error_500
def error_500
render json: {status: "ng", code: 500, content: {message: "エラーだよ"}}
end
(特定のエラーのみに対処する場合は、StandardErrorではなく個別のエラーを指定することも可能です。)
こうすると500エラー時のレスポンスもコントロールできます。
しかし、このやり方には問題点があって、エラーを吸収してしまうのでなぜエラーを吐いたかがわからなくなること。
レスポンスのjsonはフォーマットに従いつつ、ログにはエラーとそのスタックトレースを残したいです。
例外をキャッチし、エラーメッセージをログに表示するようにerror_500を書き換えます。
app/controllers/application_controller.rb
def error_500 e=nil
logger.error e.message
e.backtrace.each { |line| logger.error line }
render json: {status: "ng", code: 500, content: {message: "エラーだよ"}}
end
例外クラスのmessageとbacktraceの中身を表示することで、ログにのみエラーの詳細を記述することができます。