2008-09-09 12 views
2

Je joue avec le code routing.rb dans Rails 2.1, et essaye de le faire au point où je peux faire quelque chose d'utile avec l'exception RoutingError qui est levée quand il ne trouve pas le chemin approprié.Meilleure façon de gérer RoutingError dans Rails 2.1.x?

Ceci est un problème un peu délicat, car il existe une classe d'URL qui sont tout simplement BAD: les attaques de bot /azenv.php, les gens tapant/bar/foo/baz dans l'URL, etc ... nous Je ne veux pas ça.

Ensuite, il y a des problèmes de routage subtils, où nous voulons être notifiés:/artists/par exemple, ou ///. Dans ces situations, nous pouvons souhaiter qu'une erreur soit lancée ou non ... ou Google nous envoie des URL qui étaient valides mais qui ne le sont plus parce que les personnes les ont supprimées.

Dans chacune de ces situations, je veux un moyen de contenir, d'analyser et de filtrer le chemin que nous récupérons, ou au moins un moyen de Railsy de gérer le routage au-delà de l'URL normale de repli. Est-ce que cela existe?

EDIT:

Ainsi, le code est ici:

# File vendor/rails/actionpack/lib/action_controller/rescue.rb, line 141 

def rescue_action_without_handler(exception) 
log_error(exception) if logger 
erase_results if performed? 

# Let the exception alter the response if it wants. 
# For example, MethodNotAllowed sets the Allow header. 
if exception.respond_to?(:handle_response!) 
    exception.handle_response!(response) 
end 

if consider_all_requests_local || local_request? 
    rescue_action_locally(exception) 
else 
    rescue_action_in_public(exception) 
end 
end 

Donc, notre meilleure option est de passer outre LOG_ERROR (exception) afin que nous puissions affiner votre recherche en exceptions selon l'exception. Ainsi, dans ApplicationController

def log_error(exception) 
    message = '...' 
    if should_log_exception_as_debug?(exception) 
     logger.debug(message) 
    else 
     logger.error(message) 
    end 
end 

def should_log_exception_as_debug?(exception) 
    return (ActionController::RoutingError === exception) 
end 

Sel pour une logique supplémentaire où nous voulons une logique différente du contrôleur, les routes, etc.

Répondre

1

Il y a la méthode method_missing. Vous pouvez implémenter cela dans votre contrôleur d'application et intercepter toutes les actions manquantes, peut-être en les enregistrant et en les redirigeant vers l'action d'index du contrôleur concerné. Cette approche ignorerait tout ce qui ne peut pas être routé vers un contrôleur, ce qui est assez proche de ce que vous voulez. Sinon, je voudrais juste enregistrer toutes les erreurs, extraire l'URL et le trier par # fois où il s'est produit.

+0

L'utilisation de method_missing pourrait causer un certain nombre de problèmes. Premièrement, s'il y a un before_filter mal étiqueté qui est utilisé pour la sécurité, method_missing capturera silencieusement l'appel et vous vous retrouverez avec une erreur de routage dans votre journal et quelqu'un pourra voir une page d'administration alors qu'il ne devrait pas pouvoir. – epochwolf

4

Nooooo !!! N'implémentez pas method_missing sur votre contrôleur! Et essayez d'éviter également action_missing.

Le modèle souvent vantée est d'ajouter un itinéraire:

map.connect '*', :controller => 'error', :action => 'not_found' 

Où vous pouvez afficher une erreur appropriée.

Rails dispose également d'un mécanisme appelé rescue_action_in_public dans lequel vous pouvez écrire votre propre logique de gestion des erreurs - nous devrions vraiment le nettoyer et encourager les gens à l'utiliser. PDI! :-)

+0

Le problème est que rescue_action_in_public n'empêche pas l'enregistrement de l'erreur - le code passe: 141: def rescue_action_without_handler (exception) 142: LOG_ERROR (exception) si enregistreur ... 151: si consider_all_requests_local || requête locale? 152: rescue_action_locally (exception) 153: else 154: rescue_action_in_public (exception) 155: fin 156: fin –

Questions connexes