Pourquoi définir sa propre exception

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour à tous,
J'ai commencé à découvrir les exceptions en Ruby (quelque chose dont j'ai toujours eu un peu de mal dans tous les langages). Voici une classe que j'ai écrite :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class DenumeratorError < StandardError ; end

class Fraction
  attr_accessor :num, :denum

  def initialize(num = 0, denum = 1)
    raise DenumeratorError, 'Le dénumérateur ne peut pas être égal ou inférieur à 0.' if denum <= 0

    @num = num
    @denum = denum
  end
end

a = Fraction.new(1, 0)

Le tutoriel que je suis m'indiquait de créer ma propre classe d'exception mais sans m'expliquer à quoi cela sert. Du coup je comprend pas trop pourquoi à part être plus propre…

Merci de vos explications et de votre aide !

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0

Cas d'école, tu fais un protocole de communication, une erreur de protocole se passe, tu préfères renvoyer une exception de type "Runtime" (erreur d'exécution), ou quelque chose de plus précis qui permet éventuellement de rattraper l'exception (faire un nouvel essai par exemple), sinon donner plus d'informations ?

+0 -0

mais répond à ta question : http://sametmax.com/gestion-des-erreurs-en-python/

Vayel

Sérieux ? "ça répond à ta question" ? Y'a deux lignes et UN SEUL exemple. Ça répond pas du tout à la question de "pourquoi je devrais le faire, et quand je devrais le faire".

La réponse dépend énormément du langage. Typiquement avec Java et ses (saletés) checked exceptions, la réponse n'est pas tout à fait la même.

Je dirais que dans un langage de script, et avec des exceptions "non checked" il y a plusieurs intérêts.

D'abord, comme il est indiqué dans le lien de Vayel, ça permet de donner une info. L'exemple est assez mauvais d'ailleurs, car dans la majeur partie des langages ce type d'exception existe déjà (IllegalArgumentException en Java, ArgumentError en Ruby, …) et aucun intérêt donc de définir sa propre exception pour cela. Par contre, on peut imaginer une exception dans la configuration par exemple. Tu attends un fichier de configuration formaté comme il faut en paramètre d'une méthode. Or le fichier est corrompu, ou tout simplement le fichier est merdique. Dans ce cas, il est intéressant pour toi de définir ta propre exception tout simplement pour dire que le fichier n'est pas bon. raise ConfigError "le fichier que vous m'avez passé n'est pas formaté comme il faut, je ne peux pas le traiter" plutôt que de planter lamentablement au parsing du fichier avec une erreur un peu mystique et difficile à débugger.

L'intérêt principal c'est de "typer" ton erreur, comme si tu lui collais une étiquette.

Ainsi, un utilisateur de ta méthode (toi, dans ton code, ou quelqu'un d'autre si tu écris une API) peut traiter différemment ce cas d'erreur plutôt qu'un autre. Exemple : L'utilisateur te donne un fichier comme paramètre de ta méthode, le système plante lamentablement lorsque tu essaies d'écrire dans ce fichier. On pourrait imaginer une API système qui fait la différence entre les cas de plantage :

  • le fichier n'existe pas FileNotFoundError
  • le fichier est bloqué par un autre process LockedFileError
  • tu n'as pas la permission d'écrire dans le fichier FilePermissionError

Toutes ces exceptions pourraient dériver de la même classe FileSystemOperationError. Ainsi, lorsqu'on appelle ta méthode, soit on attrape (rescue en Ruby je crois ?) toutes les FileSystemOperationError et on affiche un message à l'utilisateur comme quoi il fait n'importe quoi, soit on traite différemment les différents cas (peut-être va-t-on créer le fichier s'il n'existe pas ? …). Tu as défini plusieurs types d'exception pour qu'on puisse les rattraper une à une. C'est un premier cas d'utilisation.

Dernier intérêt et pas des moindres : un exception est un objet. Un objet a des attributs et ces attributs servent (généralement) à décrire un état. Cela peut être intéressant dans plusieurs cas, malheureusement pas tous pertinents en Ruby :(

Par exemple, tu peux stocker de l'information quand tu crées une exception pour l'afficher plus tard (dans la méthode to_s de ta classe Exception). En gros, ton message d'erreur dépend de l'état de ton exception (par exemple pour la config ci-dessus, tu pourrais stocker toutes les erreurs de configuration et lorsque tu affiches l'exception : méthode to_s, tu construis le message dynamiquement en listant tous les champs manquants).

La (bonne) gestion des erreurs est un domaine finalement assez complexe. D'autant plus en Ruby où elle est assez critiquable (notamment le fait qu'on ne puisse pas redéfinir la méthode message de la classe Exception ou StandardError).

Le truc à retenir :

  • Essaie d'utiliser les exceptions "standard" (du langage) tant que tu peux.
  • Si vraiment tu penses qu'une de tes méthodes peut échouer pour plusieurs raisons, et que ces raisons devraient entraîner des traitements différents : définis tes propres exceptions.

Édité par Javier

Happiness is a warm puppy

+1 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte