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 ?