Подтвердить что ты не робот

Как вернуть правильные коды ошибок HTTP из приложения Ruby on Rails

У меня есть веб-приложение RoR 3.0, которое выступает в качестве поставщика API OAuth. Теперь в API я бы хотел вернуть правильные коды ошибок HTTP для потребителя API. Как это сделать?

Вот пример:

def destroy_oauth
    @item = Item.find(params[:id])
    if([email protected]? && @item.user_id == current_user.id)
        @item.destroy
        respond_to do |format|
                format.js
                format.xml
        end
    else
        raise ActionController::RoutingError.new('Forbidden')
    end
end

Итак, в случае ошибки я пытаюсь вернуть код Forbidden 403. Тем не менее, при выполнении этого я всегда получаю 404 Not Found. Как вернуть правильный код?

Или это как-то настраиваемая веб-сервер?

4b9b3361

Ответ 1

Вы должны отобразить страницу с правильным статусом.

render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)

Ответ 2

Когда вы просто указываете код состояния и нет тела, удобный способ -

head 403

Этот метод также принимает символические имена для кодов состояния, таких как

head :forbidden

Ответ 3

Согласно ActionController:: Head docs, просто используйте этот шаблон в действиях

  return head([status]) if/unless [some condition here]

Пример:

  return head(:gone) if @record.deleted?
  return head(:forbidden) unless @user.owns?(@record)

return используется, чтобы убедиться, что никакой оставшийся код в действии не будет запущен.

Ответ 5

Я думаю, у вас есть две проблемы здесь: во-первых, ваша линия @item = Item.find(params[:id]) поднимает 404, а исполнение никогда не доходит до предполагаемого (if statement). Во-вторых, вы делаете исключения и никогда их не поймаете. Попробуйте:

def destroy_oauth
   begin
     @item = Item.find(params[:id])
     if([email protected]? && @item.user_id == current_user.id)
       @item.destroy
       respond_to do |format|
          format.js
          format.xml
       end
     else
       raise ActionController::RoutingError.new('Forbidden')
     end
   rescue ActiveRecord::ResourceNotFound
     redirect_to :action => 'not_found', :status => 404 # do whatever you want here
   rescue ActionController::RoutingError
     redirect_to :action => 'forbidden', :status => 403 # do whatever you want here
   end
 end

Что-то в этом роде, но вы также упоминали, что вы строите API, поэтому, когда вы спасите ошибку, вы можете отобразить информацию об ошибке xml. Что-то вроде:

# in application_controller.rb
rescue_from ActionController::RoutingError, :with => :render_forbidden_error

private

def render_forbidden_error(e)
  render :status => e.status, :xml => e
end

Удачи. Udachi.