在Ruby中获取当前堆栈跟踪而不会引发异常

Get current stack trace in Ruby without raising an exception

我想将当前的回溯(stacktrace)记录在Rails3应用程序中,而不发生异常。你知道怎么办吗?

我为什么要这个?我试图跟踪Rails查找模板时所做的调用,以便选择要重写的进程的一部分(因为我想更改我的特定子类控制器的视图路径)。

我想从文件中调用它:gems\actionpack-3.2.3\lib\action_dispatch\middleware\templates
escues\missing_template.erb
。我知道这不是最佳实践,但我知道这是在搜索模板的堆栈的下游。


您可以使用Kernel#caller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# /tmp/caller.rb

def foo
  puts caller # Kernel#caller returns an array of strings
end

def bar
  foo
end

def baz
  bar
end

baz

输出:

1
2
3
caller.rb:8:in `bar'
caller.rb:12:in `
baz'
caller.rb:15:in `<main>'


试用使用

1
Thread.current.backtrace


我使用此项在引发异常时显示自定义错误页。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
rescue_from Exception do |exception|
  logger.error exception.class
  logger.error exception.message
  logger.error exception.backtrace.join"
"

  @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