web-dev-qa-db-fra.com

Obtenir la trace de pile actuelle dans Ruby sans déclencher une exception

Je veux enregistrer la trace actuelle (stacktrace) dans une Rails 3 app sans = une exception se produit. Une idée de comment?

Pourquoi est-ce que je veux ça? J'essaie de retracer les appels passés lorsque Rails recherche un modèle afin de pouvoir choisir une partie du processus à remplacer (car je souhaite modifier le chemin contrôleur sous-classé du mien).

Je voudrais l'appeler depuis le fichier: gems\actionpack-3.2.3\lib\action_dispatch\middleware\templates\rescues\missing_template.erb. Je sais que ce n'est pas la meilleure pratique, mais je sais que c'est en aval de la pile à partir de laquelle la recherche de modèles est effectuée.

123
JellicleCat

Vous pouvez utiliser 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

Sortie:

caller.rb:8:in `bar'
caller.rb:12:in `baz'
caller.rb:15:in `<main>'
170
KL-7

Essayez d'utiliser

Thread.current.backtrace
12
Rajat Bansal

J'utilise ceci pour afficher une page d'erreur personnalisée lorsque des exceptions sont générées.

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
4
Stefano Lampis