2012-06-20 34 views
108

我想在Rails 3應用程序登錄當前回溯(堆棧跟蹤),而不異常發生。任何想法如何?獲取紅寶石當前棧跟蹤,而不引發異常

爲什麼我要這個?我試圖追蹤Rails尋找模板時所做的調用,以便我可以選擇部分流程進行覆蓋(因爲我想更改我的特定子類控制器的視圖路徑)。

我想從文件中調用它:gems\actionpack-3.2.3\lib\action_dispatch\middleware\templates\rescues\missing_template.erb。我知道這不是最佳做法,但我知道它是從搜索模板的位置開始的棧的下游。

+4

骯髒的解決方案:引發異常出現,立即搶救,並記錄'e.backtrace'。我在與之合作的其中一個項目中見過它。不是最好的方法,但它的工作原理。不過,希望聽到別人提供更好的解決方案。 –

+0

輝煌。謝謝。 – JellicleCat

回答

155

您可以使用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>' 
+0

非常方便,非常簡單 - 謝謝! –

+0

是不是'Kernel.caller' - 帶點? 'Kernel.new.caller'沒有在這裏定義 – ecoologic

+7

不,從技術上講,'caller'是一個實例方法。由於'Kernel'模塊包含在每個Ruby類中(除了1.9中的'BasicObject'外),它可以作爲任何對象的實例方法(儘管它是私有的)。你不能僅僅因爲你不能實例化一個模塊(它沒有'new'方法)就把它叫做'Kernel.new.caller'。 –

3

我用它來顯示自定義錯誤頁時異常升高。

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 
5

嘗試使用

Thread.current.backtrace