Best Practice: domini e codici NSError per il tuo progetto / app


114

Esiste un precedente post SO relativo alla configurazione dei domini di errore per i propri framework, ma qual è la best practice per quanto riguarda l'impostazione dei domini di errore e dei codici di errore personalizzati per il proprio progetto / app ?

Ad esempio, supponendo che tu stia lavorando su un'app Core Data-intensive con molte convalide, dovresti semplicemente attenersi ai codici di errore Core Data "standard" (come NSManagedObjectValidationErrorda CoreDataErrors.h) o dovresti crearne uno tuo MyAppErrors.he definire errori con più specificità (cioè MyAppValidationErrorInvalidCombinationOfLimbs?

La creazione di un dominio di errore personalizzato e di una serie di codici di errore potrebbe disambiguare in modo significativo il codice, ma è troppo sovraccarico da mantenere e ci si deve preoccupare dei conflitti di numerazione dei codici di errore? O ci sono altre preoccupazioni qui?

Risposte:


152

Personalmente utilizzo un dominio in stile DNS inverso. Per esempio:

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

La terza parte del dominio ( @"myproject") è usata solo per differenziare gli errori di questo progetto ( "My Project") da quelli di un altro progetto ( "My Other Project"=> com.davedelong.myotherproject).

E 'un modo semplice per assicurare che io non ho intenzione di conflitto con i domini di errore di chiunque altro (se sto utilizzando il codice 3a parte), a meno che lo sviluppatore è volutamente cercando di pasticciare con solo me (che a mio avviso sarebbe altamente improbabile. ..).

Per quanto riguarda i conflitti di numerazione del codice, non preoccuparti. Finché i codici sono univoci all'interno di un dominio , dovresti essere OK.

Per quanto riguarda gli errori di traduzione, dipende da te. Qualunque cosa tu faccia, assicurati di documentarla bene. Personalmente , di solito trasmetto gli errori generati dal framework quando mi sono arrivati, poiché non sono mai abbastanza sicuro di gestire tutti i codici e tradurre tutte le informazioni utente in qualcosa di più specifico del mio progetto. I framework potrebbero cambiare e aggiungere più codici, o cambiare il significato di codici esistenti, ecc. Mi aiuta anche a identificare più specificamente da dove proviene l'errore. Ad esempio, se il mio framework StackKit genera un errore nel com.stackkitdominio, so che è un problema del framework. Tuttavia, se genera un errore in NSURLErrorDomain, allora so che proviene specificamente dal meccanismo di caricamento dell'URL.

Che cosa si potrebbe fare è catturare l'errore generato quadro e avvolgerlo in un nuovo oggetto errore che ha il vostro dominio e un codice generico, qualcosa di simile kFrameworkErrorCodeUnknowno qualcosa del genere, e quindi posizionare l'errore catturato nel userInfosotto la NSUnderlyingErrorKey. CoreData lo fa molto (ad esempio, se si tenta di eseguire save:un NSManagedObjectContexterrore di integrità della relazione, ma si verificano errori di integrità della relazione, verrà restituito un singolo errore, ma NSUnderlyingErrorKeyconterrà molte più informazioni, come nello specifico quali relazioni sono sbagliate, ecc.).


Poiché Apple utilizza anche il DNS inverso, sembra appropriato che anche altri utilizzino questo stile.
Johan Karlsson

36

Non ho abbastanza rappresentante per commentare, ma per la risposta accettata da Dave DeLong, potrebbe essere leggermente migliore da usare [[NSBundle mainBundle] bundleIdentifier]invece di @"com.myName.myProject". In questo modo, se modifichi il tuo nome o il nome del progetto, verrà riflesso accuratamente.


4
Buona idea. Se stai usando Swift, si dovrebbe usare il opzionale scartare: NSBundle.mainBundle().bundleIdentifier!(se si conosce l'identificatore fascio è impostato, che credo sarà molto probabilmente)
Juul

Perché vorresti riflettere le modifiche al nome del progetto nel dominio dell'errore?
zrslv

1
@zrxq C'è sicuramente un valore nell'avere diversi domini di errore, ma immagina di aver scritto male il tuo progetto o di aver cambiato il tuo nome e di volere che si riflettesse ovunque. Meglio averlo impostato dinamicamente che non codificato.
Connor

1
@vare Questo è molto chiaro, non capisco davvero quali vantaggi pratici fornirebbe. A quanto mi risulta, quegli identificatori devono essere univoci nel contesto dell'app, tutto qui. Ok, forse vuoi solo che siano esteticamente più gradevoli, ho capito!
zrslv

1
Sì, hai sollevato un buon punto. Ci sono momenti in cui vuoi che il dominio sia univoco, presumo ... per esempio forse se crei un SDK o un pod (cacao), vorresti che il tuo dominio di errore rifletta da dove proviene, non quello del progetto nome. EDIT: Anche io (nella mia risposta) volevo sottolineare che @ "com.myName.myProject" è identico al bundleIdentifier in questo caso, che le persone potrebbero non sapere.
Connor

4

Come creare un NSError personalizzato:

Creare prima un dizionario del messaggio di errore

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];

Quindi assegna userInfo a NSDictionary e il gioco è fatto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.