Поймать все исключения в контроллере рельсов - PullRequest
84 голосов
/ 12 сентября 2010

Есть ли способ перехватить все необнаруженные исключения в контроллере rails, например:

def delete
  schedule_id = params[:scheduleId]
  begin
    Schedules.delete(schedule_id)
  rescue ActiveRecord::RecordNotFound
    render :json => "record not found"
  rescue ActiveRecord::CatchAll
    #Only comes in here if nothing else catches the error
  end
  render :json => "ok"
end

Спасибо

Ответы [ 5 ]

193 голосов
/ 21 июля 2011

Вы также можете определить метод rescue_from.

class ApplicationController < ActionController::Base
  rescue_from ActionController::RoutingError, :with => :error_render_method

  def error_render_method
    respond_to do |type|
      type.xml { render :template => "errors/error_404", :status => 404 }
      type.all  { render :nothing => true, :status => 404 }
    end
    true
  end
end

В зависимости от вашей цели, вы также можете рассмотреть НЕ обработку исключений для каждого контроллера.Вместо этого используйте что-то вроде гема exception_handler для последовательного управления ответами на исключения.В качестве бонуса этот подход также будет обрабатывать исключения, возникающие на уровне промежуточного программного обеспечения, такие как разбор запросов или ошибки подключения к базе данных, которые ваше приложение не видит.Также может представлять интерес гем exception_notifier .

86 голосов
/ 12 сентября 2010
begin
  # do something dodgy
rescue ActiveRecord::RecordNotFound
  # handle not found error
rescue ActiveRecord::ActiveRecordError
  # handle other ActiveRecord errors
rescue # StandardError
  # handle most other errors
rescue Exception
  # handle everything else
  raise
end
27 голосов
/ 18 мая 2015

Вы можете ловить исключения по типу:

rescue_from ::ActiveRecord::RecordNotFound, with: :record_not_found
rescue_from ::NameError, with: :error_occurred
rescue_from ::ActionController::RoutingError, with: :error_occurred
# Don't resuce from Exception as it will resuce from everything as mentioned here "http://stackoverflow.com/questions/10048173/why-is-it-bad-style-to-rescue-exception-e-in-ruby" Thanks for @Thibaut Barrère for mention that
# rescue_from ::Exception, with: :error_occurred 

protected

def record_not_found(exception)
  render json: {error: exception.message}.to_json, status: 404
  return
end

def error_occurred(exception)
  render json: {error: exception.message}.to_json, status: 500
  return
end
10 голосов
/ 12 сентября 2010

rescue без аргументов спасет любую ошибку.

Итак, вы захотите:

def delete
  schedule_id = params[:scheduleId]
  begin
    Schedules.delete(schedule_id)
  rescue ActiveRecord::RecordNotFound
    render :json => "record not found"
  rescue
    #Only comes in here if nothing else catches the error
  end
  render :json => "ok"
end
0 голосов
/ 26 февраля 2016

На самом деле, если вы действительно хотите поймать все , вы просто создаете свое собственное приложение исключений, которое позволяет вам настроить поведение, которое обычно обрабатывается промежуточным программным обеспечением PublicExceptions: https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/public_exceptions.rb

Куча других ответов делятся гемами, которые делают это для вас, но на самом деле естьнет причин, по которым вы не можете просто посмотреть на них и сделать это сами.

Предупреждение: никогда не вызывайте исключение в обработчике исключений.В противном случае вы получите уродливое FAILSAFE_RESPONSE https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/show_exceptions.rb#L4-L22

Кстати, поведение в контроллере исходит от спасения: https://github.com/rails/rails/blob/4-2-stable/activesupport/lib/active_support/rescuable.rb#L32-L51

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...