Railsでrescue_fromを使った例外処理の基本!初心者向けJSONレスポンスの書き方
生徒
「Railsでエラーが起きたときに、うまく処理する方法ってあるんですか?」
先生
「もちろんありますよ。rescue_fromという機能を使えば、予期しないエラーにも対応できます。」
生徒
「それって、具体的にどんなときに使うんですか?」
先生
「例えば、存在しないデータにアクセスしたときの404エラーや、無効なデータの422エラー、予期しないバグによる500エラーなどに対応できます。初心者でもできるように、わかりやすく説明しますね!」
1. Railsの例外処理とは?
Ruby on Rails(レイルズ)は、Webアプリケーション開発に使われる人気のフレームワークです。実際の開発では、エラー(例外)が発生することがあります。たとえば、存在しない記事を見ようとしたときや、データの保存に失敗したときなどです。例外処理(れいがいしょり)とは、こういったトラブルが発生したときに、アプリが止まらずに対応するしくみです。
Railsでは、rescue_from(レスキュー・フロム)という方法を使って、例外をキャッチし、エラーに対して適切なレスポンス(返答)を返すことができます。
2. rescue_fromの基本的な使い方
rescue_fromは、Railsのコントローラの中で使うメソッドです。特定の種類のエラーが起きたときに、別のメソッドを呼び出すことができます。これにより、エラー内容に応じて、ユーザーにわかりやすいエラーメッセージを返したり、ログを記録したりできます。
以下は、存在しないデータにアクセスしたときの「404エラー」をJSON形式で返す例です。
class ApplicationController < ActionController::Base
protect_from_forgery with: :null_session
rescue_from ActiveRecord::RecordNotFound, with: :render_404
private
def render_404(exception)
render json: { error: 'データが見つかりませんでした。' }, status: :not_found
end
end
3. よく使うステータスコード:404・422・500
例外に応じて、次のようなHTTPステータスコードを使い分けることが一般的です。
- 404 Not Found:指定したデータが見つからないとき。
- 422 Unprocessable Entity:バリデーションエラーなど、データが不正なとき。
- 500 Internal Server Error:予期しないバグやサーバー側のエラー。
それぞれの例に対応したrescue_fromの書き方を見てみましょう。
4. 422エラーとバリデーションの例
ユーザーが送ってきたデータに問題があるとき、422エラーとして返すことができます。
class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordInvalid, with: :render_422
private
def render_422(exception)
render json: { error: '入力内容が正しくありません。', details: exception.record.errors.full_messages }, status: :unprocessable_entity
end
end
5. 500エラーのハンドリング例
コードのバグなどで、予想外のエラーが発生することがあります。このときは、500エラーとして処理します。ただし、開発中はそのままエラーを表示したほうが原因を特定しやすいため、本番環境だけに設定するのが一般的です。
class ApplicationController < ActionController::Base
rescue_from StandardError, with: :render_500
private
def render_500(exception)
logger.error exception.message
logger.error exception.backtrace.join("\n")
render json: { error: 'サーバー内部でエラーが発生しました。' }, status: :internal_server_error
end
end
6. JSONレスポンスとは?
JSON(ジェイソン)とは、Webでよく使われるデータ形式の一つで、「{"name":"山田"}」のように鍵と値をセットで表します。スマートフォンアプリやJavaScriptとRailsを連携する際によく使われ、機械でも人間でも読みやすいのが特徴です。
今回のように、エラーの情報もJSONで返すことで、ユーザーにとっても開発者にとってもわかりやすくなります。
7. rescue_fromを複数使うときの注意点
rescue_fromは、どのエラーに対して、どのメソッドで処理するかを明示的に書く必要があります。同じ種類のエラーを複数回指定すると、後に書かれたものが優先されます。
また、StandardErrorはすべての例外の親にあたるため、先に記述すると他のエラーがキャッチされないことがあります。順番にも注意しましょう。
8. よくあるエラーとデバッグ方法
rescue_fromを設定したのに、うまく動かないことがあります。例えば:
- 対象のエラークラスが違っている(例:RecordNotFoundと書くべきところをNotFoundにしている)
- privateメソッドが呼び出せない場合
- JSON形式が意図通りに出力されない
そんなときは、loggerを使ってエラーの中身をログに出すと、原因が分かりやすくなります。
def render_500(exception)
logger.error exception.message
logger.error exception.backtrace.join("\n")
render json: { error: 'サーバーエラーが発生しました。' }, status: :internal_server_error
end