1. ホーム
  2. ruby-on-rails

Rails で JSON 形式の 404 エラーを返す必要性

2023-07-27 10:24:15

質問

私のRailsアプリには、通常のHTMLフロントエンドとJSON APIがあります。今、もし誰かが /api/not_existent_method.json を呼び出すと、デフォルトのHTML 404ページが返されます。これを次のようなものに変更する方法はないでしょうか。 {"error": "not_found"} のようなものに変更し、HTMLフロントエンドのオリジナルの404ページはそのままにしておく方法はありますか?

どのように解決するのですか?

友人が、404エラーだけでなく500エラーも処理するエレガントなソリューションを教えてくれました。実際、これはすべてのエラーを処理します。重要なのは、すべてのエラーは例外を生成し、ラックのミドルウェアのスタックを介して、それらのいずれかによって処理されるまで上方に伝搬するということです。もっと詳しく知りたい方は、以下をご覧ください。 この素晴らしいスクリーンキャスト . Railsには独自の例外ハンドラがありますが、あまり文書化されていない exceptions_app という設定オプションで上書きできます。これで、独自のミドルウェアを書くこともできますし、このようにエラーをrailsに送り返すこともできます。

# In your config/application.rb
config.exceptions_app = self.routes

そして、これらのルートにマッチするように config/routes.rb :

get "/404" => "errors#not_found"
get "/500" => "errors#exception"

そして、これを処理するためのコントローラを作成するだけです。

class ErrorsController < ActionController::Base
  def not_found
    if env["REQUEST_PATH"] =~ /^\/api/
      render :json => {:error => "not-found"}.to_json, :status => 404
    else
      render :text => "404 Not found", :status => 404 # You can render your own template here
    end
  end

  def exception
    if env["REQUEST_PATH"] =~ /^\/api/
      render :json => {:error => "internal-server-error"}.to_json, :status => 500
    else
      render :text => "500 Internal Server Error", :status => 500 # You can render your own template here
    end
  end
end

最後にもう一つ付け加えると、開発環境では通常、railsは404や500ページをレンダリングせず、代わりにバックトレースを表示します。もし、あなたの ErrorsController の動作を確認したい場合は、バックトレースを無効にして config/enviroments/development.rb ファイルでのバックトレースを無効にします。

config.consider_all_requests_local = false