2012-06-20 16 views
108

Chcę zapisać bieżący ślad śledzenia (stosu) w aplikacji Rails 3 bez wystąpienia. Masz pomysł?Pobierz bieżący ślad stosu w Rubim bez podnoszenia wyjątku

Dlaczego tego chcę? Próbuję śledzić wywołania, które są wykonywane, gdy Railsy szukają szablonu, dzięki czemu mogę wybrać część procesu do przesłonięcia (ponieważ chcę zmienić ścieżkę widoku dla określonego kontrolera z podklasą).

Chciałbym nazwać go z pliku: gems\actionpack-3.2.3\lib\action_dispatch\middleware\templates\rescues\missing_template.erb. Wiem, że to nie jest najlepsza praktyka, ale wiem, że jest ona poniżej stosu, z którego następuje wyszukiwanie szablonów.

+4

rozwiązanie Brudny: podnieść istnieje wyjątek, uratować go od razu i zalogować 'e.backtrace'. Widziałem to w jednym z projektów, nad którymi pracuję. Nie najmilsze podejście, ale działa. Jednak mam nadzieję usłyszeć lepsze rozwiązanie od kogoś innego. –

+0

Genialny. Dziękuję Ci. – JellicleCat

Odpowiedz

155

Można użyć 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 

wyjściowa:

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

Bardzo przydatny, bardzo prosty - dzięki! –

+0

Czy to nie 'Kernel.caller' - z kropką? 'Kernel.new.caller' nie jest zdefiniowany tutaj – ecoologic

+7

Nie, technicznie' caller' jest metodą instancji. Ponieważ moduł 'Kernel' jest zawarty w każdej klasie Ruby (z wyjątkiem' BasicObject' w wersji 1.9), jest dostępny jako metoda instancji dla dowolnego obiektu (jest prywatny). Nie możesz nazwać go 'Kernel.new.caller' tylko dlatego, że nie możesz utworzyć instancji modułu (nie ma on metody' new'). –

3

używam tego, aby wyświetlić stronę błędu niestandardowego gdy Wyjątkiem są podniesione.

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

Spróbuj użyć

Thread.current.backtrace 
Powiązane problemy