web-dev-qa-db-fra.com

Devrais-je utiliser la panique ou renvoyer une erreur?

Go propose deux manières de gérer les erreurs, mais je ne sais pas lequel utiliser.

En supposant que j'implémente une fonction ForEach classique qui accepte une tranche ou une carte en tant qu'argument. Pour vérifier si un itérable est passé, je pourrais faire:

func ForEach(iterable interface{}, f interface{}) {
    if isNotIterable(iterable) {
        panic("Should pass in a slice or map!")
    }
}

ou 

func ForEach(iterable interface{}, f interface{}) error {
    if isNotIterable(iterable) {
        return fmt.Errorf("Should pass in a slice or map!")
    }
}

J'ai vu certaines discussions dire que panic() devrait être évité, mais les gens disent aussi que si le programme ne peut pas récupérer d'erreur, vous devriez panic().

Lequel devrais-je utiliser? Et quel est le principe de base pour choisir le bon?

11
laike9m

De Dave Cheney :

panics sont toujours fatals à votre programme. En paniquant, vous ne supposez jamais que votre correspondant puisse résoudre le problème. Par conséquent, panic n'est utilisé que dans des circonstances exceptionnelles, où il n'est pas possible pour votre code, ou toute personne intégrant votre code pour continuer.

Vous devez supposer qu'une panique sera immédiatement fatale, pour l'ensemble du programme ou au moins pour le goroutine actuel. Demandez-vous "quand cela se produit, l'application devrait-elle immédiatement planter?" Si oui, utilisez une panique; sinon, utilisez une erreur.

20
Adrian

Utilisez panic.

Parce que votre cas d'utilisation est de attraper une mauvaise utilisation de votre API. Cela ne devrait jamais se produire au moment de l'exécution si le programme appelle correctement votre API.

En fait, tout programme appelant votre API avec les arguments corrects se comportera de la même manière si le test est supprimé. Le test n’est là que pour échouer tôt avec un message d’erreur utile au programmeur qui a commis l’erreur. Idéalement, la panique pourrait être atteinte une fois au cours du développement lors de l'exécution de la suite de tests et le programmeur réglerait l'appel même avant de valider le code incorrect, et cette utilisation incorrecte n'atteindrait jamais la production.

Voir aussi this reponse to question La validation des paramètres de fonction utilisant des erreurs est-elle un bon modèle dans Go?.

2
dolmen

Une panique signifie généralement que quelque chose a mal tourné. Généralement utilisé pour échouer rapidement sur des erreurs qui ne devraient pas se produire pendant le fonctionnement normal, ou que nous ne sommes pas prêts à gérer avec élégance. Donc, dans ce cas, il suffit de renvoyer l'erreur, vous ne voulez pas que votre programme panique. 

0
user8067560

Si certaines exigences obligatoires ne sont pas fournies ou ne sont pas présentes au démarrage du service (par exemple, une connexion à une base de données, une configuration de service requise), vous devez utiliser la panique.

Il devrait y avoir une erreur de retour pour toute réponse de l'utilisateur ou erreur côté serveur.

0
Parmatma

Posez-vous ces questions:

  • Vous attendez-vous à ce que la situation exceptionnelle se produise, quel que soit le degré de codage de votre application? Pensez-vous qu'il devrait être utile d'informer l'utilisateur de cette condition dans le cadre de l'utilisation normale de votre application? Manipulez-le comme une erreur car l'application concerne son fonctionnement normal.
  • Cette situation exceptionnelle ne devrait-elle PAS se produire si vous codez de manière appropriée (et plutôt défensive)? (exemple: division par zéro ou accès illimité à un élément du tableau) Votre application est-elle totalement désemparée face à cette erreur? Panique.
  • Avez-vous votre API et souhaitez-vous vous assurer que les utilisateurs l'utilisent correctement? Panique. Votre API sera rarement récupérée si elle est utilisée incorrectement.
0
Luis Masuelli