web-dev-qa-db-fra.com

Meilleures pratiques - Domaines et codes NSError pour votre propre projet / application

Il y a précédent SO post concernant la configuration des domaines d'erreur pour vos propres frameworks, mais quelle est la meilleure pratique concernant la configuration des domaines d'erreur et des codes d'erreur personnalisés pour votre propre projet/application ?

Par exemple, en supposant que vous travaillez sur une application consommant beaucoup de données Core avec de nombreuses validations, si vous vous contentez des codes d'erreur Core Data "standard" (tels que NSManagedObjectValidationError from CoreDataErrors.h) ou devez-vous créer votre propre MyAppErrors.h et définir les erreurs avec plus de spécificité (c'est-à-dire MyAppValidationErrorInvalidCombinationOfLimbs?

La création d'un domaine d'erreur personnalisé et d'un ensemble de codes d'erreur pourrait considérablement lever l'ambiguïté de votre code, mais est-ce trop de surcharge à gérer et faut-il se soucier des conflits de numérotation des codes d'erreur? Ou y a-t-il d'autres préoccupations ici?

109
Neal L

J'utilise personnellement un domaine de style DNS inversé. Par exemple:

NSError * myInternalError = [NSError errorWithDomain:@"com.davedelong.myproject" code:42 userInfo:someUserInfo];

La troisième partie du domaine (@"myproject") est juste utilisé pour différencier les erreurs de ce projet ("My Project") d'erreurs dans un autre projet ("My Other Project" => com.davedelong.myotherproject).

C'est un moyen simple de m'assurer que je ne vais pas entrer en conflit avec les domaines d'erreur de quelqu'un d'autre (si j'utilise du code tiers), sauf si ce développeur essaie délibérément de jouer avec juste moi (ce qui, je crois, serait hautement improbable ...).

En ce qui concerne les conflits de numérotation de code, ne vous en faites pas. Tant que les codes sont uniques dans un domaine , vous devriez être OK.

Quant à la traduction des erreurs, cela dépend de vous. Quoi que vous fassiez, assurez-vous de bien le documenter. Personnellement , je transmets généralement les erreurs générées par le framework au fur et à mesure, car je ne suis jamais sûr de pouvoir gérer tous les codes et traduire toutes les informations utilisateur en quelque chose de plus spécifique à mon projet. Les cadres pourraient changer et ajouter plus de codes, ou changer la signification des codes existants, etc. Cela m'aide également à identifier plus précisément d'où vient l'erreur. Par exemple, si mon StackKit framework génère une erreur dans le com.stackkit domaine, je sais que c'est un problème de framework. Cependant, s'il génère une erreur dans le NSURLErrorDomain, je sais qu'il provient spécifiquement du mécanisme de chargement d'URL.

Ce que vous pourriez faire est de capturer l'erreur générée par le framework et de l'envelopper dans un nouvel objet d'erreur qui a votre domaine et un code générique, quelque chose comme kFrameworkErrorCodeUnknown ou quelque chose, puis placez l'erreur capturée dans le userInfo sous le NSUnderlyingErrorKey. CoreData fait beaucoup cela (par exemple, si vous essayez de save: an NSManagedObjectContext, mais vous avez des erreurs d'intégrité des relations, vous obtiendrez une seule erreur en retour, mais le NSUnderlyingErrorKey contiendra beaucoup plus d'informations, comme spécifiquement les relations incorrectes, etc.).

148
Dave DeLong

Je n'ai pas assez de représentant pour commenter, mais pour la réponse acceptée par Dave DeLong, il serait peut-être légèrement préférable d'utiliser [[NSBundle mainBundle] bundleIdentifier] au lieu de @"com.myName.myProject". De cette façon, si vous changez le nom ou le nom de votre projet, il sera reflété avec précision.

35
Connor

Comment créer une NSError personnalisée:

Créez d'abord un dictionnaire du message d'erreur

NSDictionary *userInfo = @{   
   NSLocalizedDescriptionKey: NSLocalizedString(@"Unknown Error - Please try again", nil),
   NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"Unknown Error - Please try again", nil),
   NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Unknown Error - Please try again", nil)
                                               };
NSError *error = [NSError errorWithDomain:[[NSBundle mainBundle] bundleIdentifier] 
  code:-58 userInfo:userInfo];

Affectez ensuite le userInfo au NSDictionary et c'est fait.

4
Mike Zriel