2012-06-20 8 views
108

に現在のバックトレース(スタックトレース)をログに記録したい場合は、例外は発生しません。どのようなアイデア?Rubyで例外を発生させずに現在のスタックトレースを取得

なぜこれをしたいですか?私は(私は特定のサブクラス化されたコントローラのビューパスを変更したいので)オーバーライドするプロセスの一部を選択できるように、Railsがテンプレートを探すときに行われる呼び出しをトレースしようとしています。

私はファイルから電話したいと思います。私はそれがベストプラクティスではないことを知っていますが、テンプレートの検索が行われるスタックの下流にあることはわかっています。

# /tmp/caller.rb 

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

def bar 
    foo 
end 

def baz 
    bar 
end 

baz 

出力:

+4

ダーティソリューションを使用してみてください:そこに例外を発生させ、すぐにそれを救出し、e.backtrace' 'ログインします。私が取り組んでいるプロジェクトの1つでそれを見てきました。一番良いアプローチではありませんが、うまくいきます。しかし、誰かからより良い解決策を聞いてほしいです。 –

+0

ブリリアント。ありがとうございました。 – JellicleCat

答えて

155

あなたはKernel#caller使用することができます

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'を除く)に含まれているので、どのオブジェクトでもインスタンスメソッドとして利用できます(プライベートですが)。 'Kernel.new.caller'という名前は、モジュールをインスタンス化できない(' new'メソッドはありません)という理由だけでは呼び出すことができません。 –

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 
関連する問題