Utiliser des assertions par opposition à des exceptions?

38

Souvent, lorsque j'écris une fonction, je veux m'assurer que ses entrées sont valides afin de détecter ces erreurs le plus tôt possible (je crois que cela s'appelle des préconditions). Quand une condition préalable échoue, j'ai toujours levé une exception. Mais je commence à douter que ce soit la meilleure pratique et, sinon, des affirmations seraient plus appropriées.

Alors, quand devrais-je faire quoi: quand est-il approprié d'utiliser une assertion et quand est-il approprié de lever une exception?

Gablin
la source
3
Je pense que cette question devrait être posée sur stackoverflow, bien qu’elle y ait probablement déjà été posée une douzaine de fois. Vous y trouverez peut-être déjà beaucoup de réponses.
user281377

Réponses:

50

Les assertions ne doivent être utilisées que pour vérifier des conditions dont la fausse doit être logiquement impossible (lire: contrôles de cohérence). Ces conditions ne doivent être basées que sur les entrées générées par votre propre code. Toute vérification basée sur des entrées externes doit utiliser des exceptions.

Une règle simple que j'ai tendance à suivre est la vérification des arguments de fonctions privées avec des assertions et l'utilisation d'exceptions pour les arguments de fonctions publiques / protégées.

Note to self - pensez à un nom
la source
Bon point sur l'utilisation d'exceptions pour les entrées externes. J'ajouterais aussi des sorties à cela aussi - des problèmes en essayant de créer / écrire dans un fichier / base de données, etc.
ChrisF
13
Et inévitablement, vous constaterez que ces affirmations sont déclenchées dans la production. +1 pour vérifier des données privées avec des assertions! Peut-être pourriez-vous dire "utilise des assertions lorsque vous avez le plein contrôle des entrées"?
Frank Shearar
1
Au moins en Java, vous devez généralement activer le contrôle d'assertion avec le paramètre de ligne de commande -ea. Cela signifie que les assertions sont en réalité des no-ops, à moins que vous ne les activiez explicitement.
Bill Michell
29

Les assertions sont utilisées pour rechercher des erreurs de programmation. Vos programmes doivent fonctionner aussi bien lorsque toutes les assertions sont supprimées.

Les exceptions, par contre, concernent des situations pouvant survenir même lorsque le programme est parfait; ils sont causés par des influences externes, telles que le matériel, le réseau, les utilisateurs, etc.

utilisateur281377
la source
C'est un très bon moyen de le dire. Si l'utilisateur entre quelque chose incorrect, lève une exception. Si la saisie est correcte mais que quelque chose ne va pas, lancez une affirmation.
Mateen Ulhaq
3

La pratique de programmation typique consiste à compiler des assertions à partir de versions de production / publication. Les assertions aideront uniquement lors des tests internes à détecter l'échec des hypothèses. Vous ne devez pas assumer le comportement d'agences externes, vous ne devez donc pas affirmer sur les événements du réseau ou de l'utilisateur. Il est également recommandé d'écrire du code de traitement pour les versions de production en cas d'échec d'une assertion.

Par exemple en C,

int printf(const char *fmt, ...)
{
  assert(fmt);  // may fail in debug build but not in production build
  if (!fmt) return -1; // handle gracefully in production build
  ...
}

Les exceptions doivent être intégrées aux versions de production. L'alternative à l'exception est de renvoyer une erreur et non des assertions.

aufather
la source
2
Je ne pense pas que ce soit une bonne idée de mettre un comportement gracieux derrière une affirmation pour la même condition. Inévitablement, du fait que le comportement gracieux n'existe que dans la version de production, le code qui était censé traiter ce comportement gracieux sera mal testé et plantera tout aussi mal, sinon pire, que le code l'aurait été s'il n'était pas protégé.
Sebastian Redl
0

Un problème avec les assertions pour moi est qu'elles sont désactivées par défaut en Java.

Nous utilisons une stratégie d’échec en premier selon laquelle le programme - qui peut fonctionner sans surveillance depuis des années - doit s’arrêter le plus tôt possible pour éviter la corruption des données en cas de données incorrectes (sous une forme inattendue). C’est pour cela que nous utilisons la vérification, et en utilisant des assertions, nous risquons fondamentalement qu’ils ne soient pas actifs.


la source