program tip

Rails에서 JSON 형식의 404 오류를 반환해야합니다.

radiobox 2020. 10. 19. 07:55
반응형

Rails에서 JSON 형식의 404 오류를 반환해야합니다.


Rails 앱에 일반 HTML 프런트 엔드와 JSON API가 있습니다. 이제 누군가 호출 /api/not_existent_method.json하면 기본 HTML 404 페이지가 반환됩니다. {"error": "not_found"}HTML 프런트 엔드의 원본 404 페이지를 그대로 유지하면서 이것을 변경하는 방법이 있습니까?


한 친구가 404뿐만 아니라 500 개의 오류도 처리하는 우아한 솔루션을 알려주었습니다. 실제로 모든 오류를 처리합니다. 핵심은 모든 오류가 랙 미들웨어 중 하나가 처리 할 때까지 스택을 통해 위쪽으로 전파되는 예외를 생성한다는 것입니다. 더 많은 것을 배우고 싶다면 이 훌륭한 스크린 캐스트를 시청할 수 있습니다 . Rails에는 예외에 대한 자체 처리기가 있지만 덜 문서화 된 exceptions_app구성 옵션으로 재정의 할 수 있습니다 . 이제 자신의 미들웨어를 작성하거나 다음과 같이 오류를 다시 레일로 라우팅 할 수 있습니다.

# 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

마지막으로 추가 할 사항 : 개발 환경에서 레일은 일반적으로 404 또는 500 페이지를 렌더링하지 않고 대신 역 추적을 인쇄합니다. 당신이보고 싶은 경우 ErrorsController개발 모드에서 작업을 한 다음에 역 추적 물건을 사용하지 않도록 config/enviroments/development.rb파일.

config.consider_all_requests_local = false

형식 (json) 및 api 관련 메서드를 설정하는 별도의 API 컨트롤러를 만들고 싶습니다.

class ApiController < ApplicationController
  respond_to :json

  rescue_from ActiveRecord::RecordNotFound, with: :not_found
  # Use Mongoid::Errors::DocumentNotFound with mongoid

  def not_found
    respond_with '{"error": "not_found"}', status: :not_found
  end
end

RSpec 테스트 :

  it 'should return 404' do
    get "/api/route/specific/to/your/app/", format: :json
    expect(response.status).to eq(404)
  end

물론, 다음과 같이 보일 것입니다.

class ApplicationController < ActionController::Base
  rescue_from NotFoundException, :with => :not_found
  ...

  def not_found
    respond_to do |format|
      format.html { render :file => File.join(Rails.root, 'public', '404.html') }
      format.json { render :text => '{"error": "not_found"}' }
    end
  end
end

NotFoundException예외의 실제 이름 아닙니다 . Rails 버전과 원하는 동작에 따라 다릅니다. Google 검색으로 쉽게 찾을 수 있습니다.


당신 의 끝에 넣어보십시오 routes.rb:

match '*foo', :format => true, :constraints => {:format => :json}, :to => lambda {|env| [404, {}, ['{"error": "not_found"}']] }

참고 URL : https://stackoverflow.com/questions/10253366/need-to-return-json-formatted-404-error-in-rails

반응형