我想在 Rails 3 应用程序中记录当前的回溯(堆栈跟踪),而不会发生异常。知道怎么做吗?
我为什么要这个?我正在尝试跟踪 Rails 查找模板时进行的调用,以便我可以选择要覆盖的过程的一部分(因为我想更改我的特定子类控制器的视图路径)。
我想从文件中调用它:gems\actionpack-3.2.3\lib\action_dispatch\middleware\templates\rescues\missing_template.erb
。我知道这不是最佳实践,但我知道它位于堆栈的下游,从那里开始搜索模板。
e.backtrace
。我在我正在处理的一个项目中看到了它。不是最好的方法,但它有效。不过,希望从其他人那里听到更好的解决方案。
您可以使用 Kernel#caller
:
# /tmp/caller.rb
def foo
puts caller # Kernel#caller returns an array of strings
end
def bar
foo
end
def baz
bar
end
baz
输出:
caller.rb:8:in `bar'
caller.rb:12:in `baz'
caller.rb:15:in `<main>'
尝试使用
Thread.current.backtrace
Kernel#caller
省略了当前方法。例如 MyClass.new.returns_caller => ["(irb):42:in 'irb_binding'",...]
不如 MyClass.new.returns_thread_backtrace => ["(irb):38:in 'backtrace'","(irb):38:in 'returns_thread_backtrace'","(irb):43:in 'irb_binding'",...]
有用
当引发异常时,我使用它来显示自定义错误页面。
rescue_from Exception do |exception|
logger.error exception.class
logger.error exception.message
logger.error exception.backtrace.join "\n"
@exception = exception
# ExceptionNotifier::Notifier.exception_notification env, @exception
respond_to do |format|
if [AbstractController::ActionNotFound, ActiveRecord::RecordNotFound, ActionController::RoutingError, ActionController::UnknownAction].include?(exception.class)
format.html { render :template => "errors/404", :status => 404 }
format.js { render :nothing => true, :status => 404 }
format.xml { render :nothing => true, :status => 404 }
elsif exception.class == CanCan::AccessDenied
format.html {
render :template => "errors/401", :status => 401 #, :layout => 'application'
}
# format.js { render :json => { :errors => [exception.message] }, :status => 401 }
# format.js { render :js => 'alert("Hello 401")' }
format.js { render :template => 'errors/401.js.erb' }
else
ExceptionNotifier::Notifier.exception_notification(env, exception).deliver
format.html { render :template => "errors/500", :status => 500 } #, :layout => 'im2/application' }
# format.js { render :nothing => true, :status => 500 }
format.js { render :template => 'errors/500.js.erb' }
end
end
end
Kernel.caller
- 带点吗?Kernel.new.caller
在这里没有定义caller
是一个实例方法。由于Kernel
模块包含在每个 Ruby 类中(1.9 中的BasicObject
除外),因此它可以作为任何对象的实例方法使用(尽管它是私有的)。您不能仅仅因为无法实例化模块(它没有new
方法)而将其称为Kernel.new.caller
。Rails.logger.debug caller.join("\n")
或puts caller.join("\n")
。谢谢。