前回、【Ruby】カスタム例外の作成と利用に関する基礎知識でRubyにおけるカスタム例外の基礎知識について紹介しました。
今回はRailsアプリケーションでカスタム例外を利用する際の定義パターンについて紹介します。
クラス内にカスタム例外のクラスを定義する
あるクラスでしか利用しない独自の例外クラスを定義したい場合や、カスタム例外名の重複を防ぎたい場合に利用されるパターンです。
クラス内にカスタム例外を定義することで名前空間つきのカスタム例外が作成できます。
たとえば、リクエスト元のIPアドレスを制限するモジュールでカスタム例外を利用すると以下のようになります。コードの詳細解説は【Rails】APIリクエストにIPアドレスの制約をつける方法で紹介しています。
app/controllers/concerns/ip_restrictable.rb
module IpRestrictable
class IpAddressInvalidError < StandardError
def initialize(address)
super("許可していないIPアドレスからのリクエスト - IP address=#{address}")
end
end
extend ActiveSupport::Concern
included do
before_action :validate_ip_adress
end
private
def validate_ip_adress
address = request.remote_ip
raise IpRestrictable::IpAddressInvalidError.new(address) unless allow_ip_addresses.include?(address)
end
def allow_ip_addresses
IPAddr.new(Rails.application.config_for(:ip_address)["allow_api_access"])
end
end
カスタム例外の定義一覧を記載する独自クラスを用意する
任意のクラスで利用するカスタム例外を定義したい場合に利用されるパターンです。
具体的な利用例は以下の通りです。
config/initilizers/exceptions.rb
class IpAddressInvalidError < StandardError; end
app/controllers/concerns/ip_restrictable.rb
module IpRestrictable
extend ActiveSupport::Concern
included do
before_action :validate_ip_adress
end
private
def validate_ip_adress
raise IpAddressInvalidError unless allow_ip_addresses.include?(request.remote_ip)
end
def allow_ip_addresses
IPAddr.new(Rails.application.config_for(:ip_address)["allow_api_access"])
end
end
app/controllers/application_controller.rb
class ApplicationController < ActionController::API
rescue_from IpAddressInvalidError, with: :render403
private
def render403(exception = nil)
render json: { message: "Invalid Ip Address" }, status: :forbidden
end
end
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!