4 votes

Où et comment traiter les exceptions des rails ?

Je suis actuellement impliqué dans le développement d'une grande application rails qui s'interface avec un autre produit via une gemme API personnalisée. Cela a conduit à une sorte de capture d'erreur très étrange. Par exemple, lorsque nous interagissons avec l'autre produit, celui-ci peut renvoyer une erreur d'authentification, ce à quoi nous nous attendons. Nous capturons alors cette erreur dans notre gemme API et lançons une exception, qui est ensuite capturée et relayée à l'utilisateur dans la vue.

Je n'aime pas cette méthode de détection des erreurs pour plusieurs raisons :

  • Il ne semble pas que nous devions nous attendre à des exceptions et les utiliser dans notre logique. Par exemple, il arrive que l'on veuille écraser un objet - on attrape donc l'exception "object already exists" et on enregistre quand même notre modèle.
  • Elle nécessite un grand nombre de corrections d'erreurs spécifiques. Il y a plusieurs zones dans le code où nous avons des if-eles qui vérifient certaines erreurs et redirigent en conséquence.

Cela dit, devrais-je étoffer la gemme API pour avoir des fonctions plus simples qui ne lèvent pas d'exceptions ? Est-ce que

if user.has_permission_in_product?
  if object.doesnt_exist_in_product?
    do something
  else
    redirect somewhere with errors
  end
else
  redirect somewhere else with errors
end

préférable à

begin
  do something
rescue APIError => e
  if e.message =~ "no permission"
    redirect somewhere with errors
  elsif e.message =~ "already exists"
    redirect somewhere else with errors
  end
end

En outre, si la première solution est préférable, comment traiter les erreurs d'API réelles qui peuvent être lancées dans ces fonctions ? Doit-on les regrouper dans un rescue_from dans le contrôleur ?

Est-il préférable d'attraper et de traiter les exceptions dans le modèle, ou de les lancer dans le modèle et de les traiter dans le contrôleur ?

12voto

Damien MATHIEU Points 13805

Vous êtes à la recherche de sauver_de ?

Dans votre contrôleur, procédez comme suit :

class MyController < ApplicationController
    rescue_from ActiveRecord::RecordNotFound, :with => :render_missing

    def render_missing
        render 'This is a 404', :status => 404
    end
end

La méthode render_missing sera exécutée à chaque fois qu'un fichier ActiveRecord::RecordNotFound est soulevée.
Vous pouvez l'utiliser avec toutes les classes d'exception que vous souhaitez. Et vous n'avez plus besoin de begin/rescue dans vos contrôleurs.

Bien sûr, toute exception soulevée dans un modèle pourrait également être attrapée par rescue_from.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X