Поймать NameError и NoMethodError с помощью escape_from в Rails 3

У меня есть этот ApplicationController:

class ApplicationController < ActionController::Base
  before_filter :class_breadcrumb
end

Я требую, чтобы каждый контроллер определял свой собственный метод class_breadcrumb(). И я хотел бы показать сообщение, не вызывая исключения, если этот метод не существует. Наконец, я хочу, чтобы все остальные исключения возвращались к стандартной странице xml 500.

Я чувствовал, что с этим блоком Rescue_from будет довольно просто справиться:

rescue_from "NameError" do |e|
  if e.to_s.include?('class_breadcrumb')
    flash.now["alert-danger"] = "You didn't provide a breadcrumb for #{request.fullpath}! Please send us a feedback including this message!"
    render params[:action]
  else
    # default behavior
    render :xml => e, :status => 500
  end
end

И это работает! Но когда внутри контроллера возникает какое-либо другое исключение... предположим, я вызываю неопределенный метод следующим образом:

<%= undefined_method_that_raise_an_exception %>

Я вижу пустую страницу с этим сообщением:

Внутренняя ошибка сервера

нет неявного преобразования NameError в String

Что не так с моим кодом?


person Mich Dart    schedule 05.10.2013    source источник


Ответы (1)


Наконец-то я понял это!

# rescue NoMethodError
def method_missing(method, *args, &block)
  if method == 'class_breadcrumb'
    flash.now["alert-danger"] = "You didn't provide a breadcrumb for #{request.fullpath}! Please send us a feedback including this message!"
    render params[:action]
  end
end

Это метапрограммирование Ruby! Вот почему я только что убедил себя купить эту книгу и избавиться от боли: http://pragprog.com/book/ppmetr/metaprogramming-ruby

person Mich Dart    schedule 05.10.2013
comment
Это, безусловно, один из способов обойти проблему, с которой вы столкнулись, но я бы порекомендовал вам добавить else для вашего if, который вызывает super, чтобы method_missing продолжал цепочку поиска методов, а соответствующие исключения вызывались для методов, отличных от class_breadcrumb. - person carols10cents; 06.10.2013