Ruby classes d'erreur personnalisées: l'héritage de l'attribut message
Je n'arrive pas à trouver beaucoup d'informations sur les classes d'exception.
Ce que je sais,
Vous pouvez déclarer votre erreur personnalisés de la classe et de laisser hériter de StandardError
, de sorte qu'il peut être rescue
d:
class MyCustomError < StandardError
end
Cela vous permet de la soulever à l'aide de:
raise MyCustomError, "A message"
et plus tard, vous obtenez ce message lorsque le sauvetage
rescue MyCustomError => e
puts e.message # => "A message"
Ce que je ne sais pas
Je veux donner à mon exception de certains champs personnalisés, mais je veux hériter de la message
attribut de la classe parent. J'ai trouvé la lecture de sur ce sujet que @message
n'est pas une variable d'instance de la classe exception, donc j'ai peur que mon héritage ne fonctionne pas.
Quelqu'un peut-il me donner plus de détails à ce propos? Comment pourrais-je mettre en œuvre une erreur personnalisée classe avec un object
attribut? Est la suivante correct:
class MyCustomError < StandardError
attr_reader :object
def initialize(message, object)
super(message)
@object = object
end
end
Et puis:
raise MyCustomError.new(anObject), "A message"
pour obtenir:
rescue MyCustomError => e
puts e.message # => "A message"
puts e.object # => anObject
ça va fonctionner, et si elle le fait, est-ce la bonne façon de faire les choses?
- Ne pas
rescue Exception => e
. Il est plus large que la valeur par défautrescue => e
qui s'étend deStandardError
, et les prises de à tout, y compris les touches Ctrl+C. je feraisrescue MyCustomError => e
. - J'ai édité ma question pour la plus bonne approche.
Vous devez vous connecter pour publier un commentaire.
raise
déjà définit le message de sorte que vous n'avez pas à passer au constructeur:J'ai remplacé
rescue Exception
avecrescue MyCustomError
, voir Pourquoi est-il un mauvais style de " sauvetage Exception => e` en Ruby?.rescue Exception
, mais pourquoi ne pasrescue MyCustomError
?raise MyCustomError, "a message"
sansnew
, un "message" ne seront pas réglées.Compte tenu de ce que le rubis de la documentation de base de
Exception
, à partir de laquelle toutes les autres erreurs hériter, unis au sujet de#message
http://ruby-doc.org/core-1.9.3/Exception.html#method-i-message
J'opterais pour la redéfinition de
to_s
/to_str
ou l'initialiseur. Voici un exemple où nous voulons savoir, principalement de l'homme lisible, quand un service n'a pas à faire quelque chose.REMARQUE: La deuxième stratégie ci-dessous utilise les rails jolie chaîne de méthodes, telles que
demodualize
, qui peut être un peu compliqué, et donc potentiellement pas judicieux de faire une exception. Vous pouvez également ajouter d'autres arguments à la signature de la méthode, si vous avez besoin d'.Primordial #to_s Stratégie pas #to_str, il fonctionne différemment
Sortie De La Console
Primordial #initialiser Stratégie
C'est la stratégie la plus proche pour les implémentations je l'ai utilisé dans les rails. Comme indiqué ci-dessus, il utilise le
demodualize
,underscore
, ethumanize
ActiveSupport
méthodes. Mais cela pourrait facilement être retiré, comme dans la stratégie précédente.Sortie De La Console
De Démonstration De L'Outil De
C'est une démo pour montrer sauvetage et à la messagerie de ce qui précède la mise en œuvre. La classe de soulever les exceptions est un faux API pour Cloudinary. Juste dump l'une des stratégies ci-dessus dans votre console rails, suivie par les ce.
Votre idée est la bonne, mais la façon dont vous l'appelez, est faux. Il devrait être
raise
mot-clé ou quelque chose.initialize
de prendre deux arguments.new
passe les arguments pourinitialize
.raise(BillRowError.new(:roamingcalls, @index), "Roaming Calls field missing")
. Alors qu'il appelleraise
avec deux paramètres: un nouveauBillRowError
objet, et de son message. Je suis juste confus par la syntaxe... Sur d'autres tutoriels, je vois toujours les choses comme ceci:raise Error, message
raise
; c'est assez bien souple. Le problème, c'est que vous avez définiinitialize
de prendre deux arguments et ne lui a donné un. Regardez dans votre exemple.BillRowError.new(:roamingcalls, @index)
est donné deux arguments.raise
, dans cet exemple, le message, également défini comme message sur leBillRowError
objet? Désolé si cette discussion vous ennuie, merci pour votre explication à ce jour.Je voulais faire quelque chose de similaire. Je voulais passer un objet à #nouveauté et de l'ensemble de message basé sur un traitement de l'objet passé. Les œuvres suivantes.
Notez que si vous ne déclarez pas
attr_accessor :message
alors il ne fonctionnera pas. Abordant le cas des OP problème, vous pouvez aussi passer le message comme un argument supplémentaire et stocker tout ce que vous voulez. La partie cruciale semble être primordial #message.