Je travaille avec Rails 6. J'ai défini une classe d'erreur à l'intérieur de la classe qui la soulève :
class MyClass < ApplicationRecord
...
class CustomError < StandardError
attr_reader :param
def initialize(param)
@param = param
end
end
end
J'essaie de le sauver dans le code client, mais cela ne marche pas :
rescue MyClass::CustomError => e
D'autre part, cela soulève uninitialized constant
sur CustomError
Le résultat est exactement ce à quoi je m'attendais :
rescue CustomError => e
Qu'en est-il de ceci ?
rescue MyClass::CustomError => e
raise unless e.instance_of? MyClass::CustomError
# do some real error handling
...
end
instance_of?
ne reconnaît pas l'erreur et relance.
J'ai même essayé :
class MyClass < ApplicationRecord
...
end
class MyClass::CustomError < StandardError
attr_reader :para
def initialize(param)
@param = param
end
end
Ce n'est pas mieux.
2 choses qui avoir ont travaillé sont tous deux des odeurs de code :
-
Définition de l'erreur en dehors de la classe contenante, sans espacement des noms (namespacing)
-
Sauvegarde d'une erreur générique :
rescue => e
Il fonctionne également très bien dans MiniTest :
e = assert_raises(MyClass::CustomError) do
...
end
On a l'impression que le nom de la classe d'erreur CustomError
ne se résout tout simplement pas à MyClass::CustomError
dans le code de l'application, mais le code du client a besoin du nom de classe contenant la classe pour la résoudre.
Il est plus probable que je fasse quelque chose d'un peu naïf/stupide !
Informations complémentaires :
- Ruby 2.7.1
- Rails 6.0.3.3
- La classe qui soulève l'erreur et la classe qui la traite sont toutes deux des classes de modèle (ce qui est un peu inhabituel)
- La classe d'exécution à l'origine de l'erreur est un enfant de
MyClass
:MyChild < MyClass < ActiveRecord
(également inhabituel)