あんパン

こしあん以外は認めない

Sinatraで独自エラーをraiseしたら勝手にエラーページを生成する方法

SinatraのModularアプリケーションではStandardErrorを継承したMyErrorみたいなのをキャッチして特定の動作をすることができる。

MyError

class MyError < StandardError
  def self.code
    402
  end

  def self.message
    '寿司を食べるには支払いが必要です'
  end
end

Sinatraのアプリケーション本体

# ~略~
  error MyError do
    status MyError.code
    MyError.message
  end

  get '/' do
    raise MyError if params[:sushi_payment].empty?
    '寿司'
  end
# ~略~

だいたいこんな感じ(適当)

これを応用して、module内に独自のエラーを定義しまくって、そのエラーをraiseしたら勝手にエラーページを生成するようにする。

エラーの定義

module Error
  class PaymentRequiredToEatSushi < StandardError
    def self.code
      402
    end

    def self.message
      '寿司を食べるには支払いが必要です'
    end
  end

  class SushiNotFound < StandardError
    def self.code
      404
    end

    def self.message
      '寿司屋が見つかりませんでした。'
    end
  end
end

Sinatraのアプリケーション本体

# ~略~
Error.constants.each do |exception_name|
  exception = Error.const_get(exception_name)
  error exception do
    status exception.code
    # テンプレートにexception渡す処理
  end
end
# ~略~

あとは適当にraise Errors::SushiNotFoundとかやるとその後の処理がすべてキャンセルされて定義したエラーページが表示される。

APIを書いていて、ユーザの非存在とか他の情報の非存在とかをすべて区別して表示したいときとかに便利。