APIにおけるエラーハンドリング

concernsディレクトリにエラー処理ファイルを作成する。

※concernsは以下のような目的で使われる。
・複数のコントローラー(モデル)から利用される処理を共通化する。
・ある特定のまとまった処理を切り出して見通しをよくする。

# controllers/concerns/api/exception_handler.rb

module Api::ExceptionHandler
  # モジュールを読み込んだときにインスタンスメソッドもクラスメソッドも両方読み込める。
  extend ActiveSupport::Concern

  # このブロック内にメソッドを定義しておくと、モジュールがincludeされたあとににそのメソッドが動作する。
  included do
    rescue_from StandardError, with: :render_500
    rescue_from ActiveRecord::RecordNotFound, with: :render_404
  end

  private

  def render_400(exception = nil, messages = nil)
    render_error(400, 'Bad Request', exception&.message, *messages)
  end

  def render_404(exception = nil, messages = nil)
    render_error(404, 'Record Not Found', exception&.message, *messages)
  end

  def render_500(exception = nil, messages = nil)
    render_error(500, 'Internal Server Error', exception&.message, *messages)
  end

  def render_error(code, message, *error_messages)
    response = {
      message: message,
      # compactメソッドは配列から「nil」を取り除いた新しい配列を返す。
      errors: error_messages.compact
    }

    render json: response, status: code
  end
end


該当のコントローラーでinclude。

module Api
  module V1
    class BaseController < ApplicationController
      include Api::ExceptionHandler
    end
  end
end



参考記事:
RailsでAPIを作るときのエラー処理について | Yucchiy's Note
rails concernの使い方 - Qiita
include、extend、ActiveSupport::Concernざっくりまとめ - Qiita
Rubyにおける可変長引数の使い方を現役エンジニアが解説【初心者向け】 | TechAcademyマガジン
【Rails5】rescue_fromによる例外処理:アプリ固有のエラーハンドリングとエラーページ表示 - Qiita
要素が「nil」のものを取り除く - 配列(Array)クラス - Ruby入門
Rubyのextendメソッドの使い方を現役エンジニアが解説【初心者向け】 | TechAcademyマガジン