2012-06-20 10 views
108

Ich möchte die aktuelle Backtrace (StackTrace) in einer Rails 3 App ohne eine Ausnahme auftreten. Irgendeine Idee wie?Aktuelle Stack-Trace in Ruby ohne eine Ausnahme auslösen

Warum möchte ich das? Ich versuche, die Aufrufe zu verfolgen, die ausgeführt werden, wenn Rails nach einer Vorlage sucht, damit ich einen Teil des Prozesses auswählen kann, der überschrieben werden soll (da ich den Ansichtspfad für einen bestimmten Unterklasse-Controller von mir ändern möchte).

Ich möchte es aus der Datei nennen: gems\actionpack-3.2.3\lib\action_dispatch\middleware\templates\rescues\missing_template.erb. Ich weiß, dass das nicht die beste Vorgehensweise ist, aber ich weiß, dass es sich hinter dem Stapel befindet, von dem aus die Suche nach Vorlagen erfolgt.

+4

Schmutzige-Lösung: eine Ausnahme dort erhöhen, retten sie sofort und melden Sie sich 'e.backtrace'. Ich habe es in einem der Projekte gesehen, mit denen ich arbeite. Nicht der netteste Ansatz, aber es funktioniert. Hoffe, eine bessere Lösung von jemand anderem zu hören. –

+0

Brilliant. Vielen Dank. – JellicleCat

Antwort

155

Sie können Kernel#caller verwenden:

# /tmp/caller.rb 

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

def bar 
    foo 
end 

def baz 
    bar 
end 

baz 

Ausgang:

caller.rb:8:in `bar' 
caller.rb:12:in `baz' 
caller.rb:15:in `<main>' 
+0

Sehr praktisch, sehr einfach - danke! –

+0

Ist es nicht 'Kernel.caller' - mit einem Punkt? 'Kernel.new.caller' ist hier nicht definiert – ecoologic

+7

Nein, technisch ist' caller' eine Instanzmethode. Da 'Kernel'-Modul in jeder Ruby-Klasse enthalten ist (außer' BasicObject' in 1.9), ist es als Instanzmethode für jedes Objekt verfügbar (es ist jedoch privat). Sie können es nicht als 'Kernel.new.caller' bezeichnen, weil Sie ein Modul nicht instanziieren können (es hat keine' neue' Methode). –

3

Ich benutze dies eine benutzerdefinierte Fehlerseite angezeigt wird, wenn Ausnahme ausgelöst werden.

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

Versuchen

Thread.current.backtrace 
Verwandte Themen