Mejores prácticas: dominios y códigos NSError para su propio proyecto / aplicación

114

Existe una publicación de SO anterior sobre la configuración de dominios de error para sus propios marcos, pero ¿cuál es la mejor práctica con respecto a la configuración de dominios de error y códigos de error personalizados para su propio proyecto / aplicación ?

Por ejemplo, suponiendo que está trabajando en una aplicación intensiva en datos centrales con muchas validaciones, ¿debería seguir con los códigos de error de datos centrales "listos para usar" (como NSManagedObjectValidationErrordesde CoreDataErrors.h) o debería crear los suyos propios MyAppErrors.hy definir errores con más especificidad (es decir MyAppValidationErrorInvalidCombinationOfLimbs,?

La creación de un dominio de error personalizado y un conjunto de códigos de error podría eliminar la ambigüedad de su código de manera significativa, pero ¿es demasiado para mantener y hay que preocuparse por los conflictos de numeración de códigos de error? ¿O hay otras preocupaciones aquí?

Neal L
fuente

Respuestas:

152

Yo personalmente uso un dominio de estilo DNS inverso. Por ejemplo:

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

La tercera parte del dominio ( @"myproject") solo se usa para diferenciar los errores de este proyecto ( "My Project") de los errores en otro proyecto ( "My Other Project"=> com.davedelong.myotherproject).

Es una forma sencilla de asegurarme de que no voy a entrar en conflicto con los dominios de error de nadie más (si estoy usando código de terceros), a menos que ese desarrollador intente deliberadamente meterse solo conmigo (lo que creo que sería muy poco probable. ..).

En cuanto a los conflictos de numeración de códigos, no se preocupe por eso. Siempre que los códigos sean únicos dentro de un dominio , debería estar bien.

En cuanto a los errores de traducción, eso depende de usted. Hagas lo que hagas, asegúrate de documentarlo bien. Personalmente , generalmente solo paso los errores generados por el marco a medida que me llegan, ya que nunca estoy seguro de que manejaré todos los códigos y traduciré toda la información del usuario en algo más específico para mi proyecto. Los marcos podrían cambiar y agregar más códigos, o cambiar el significado de los códigos existentes, etc. También me ayuda a identificar más específicamente de dónde vino el error. Por ejemplo, si mi marco StackKit genera un error en el com.stackkitdominio, sé que es un problema de marco. Sin embargo, si genera un error en el NSURLErrorDomain, entonces sé que proviene específicamente del mecanismo de carga de URL.

Lo que podría hacer es capturar el error generado por el marco y envolverlo en un nuevo objeto de error que tenga su dominio y un código genérico, algo como kFrameworkErrorCodeUnknowno algo, y luego colocar el error capturado en userInfoel NSUnderlyingErrorKey. CoreData hace esto mucho (por ejemplo, si intenta save:an NSManagedObjectContext, pero tiene errores de integridad de relación, obtendrá un solo error, pero NSUnderlyingErrorKeycontendrá mucha más información, como específicamente qué relaciones son incorrectas, etc.).

Dave DeLong
fuente
Dado que Apple también usa DNS inverso, parece apropiado que otros usen este estilo también.
Johan Karlsson
36

No tengo suficiente representante para comentar, pero para la respuesta aceptada por Dave DeLong, podría ser un poco mejor usar en [[NSBundle mainBundle] bundleIdentifier]lugar de @"com.myName.myProject". De esta manera, si cambia su nombre o el nombre del proyecto, se reflejará con precisión.

Connor
fuente
4
Buena idea. Si está usando Swift, debe usar el opcional sin empaque: NSBundle.mainBundle().bundleIdentifier!(si sabe que el identificador del paquete está configurado, lo que supongo que será más probable)
Juul
¿Por qué querría reflejar los cambios de nombre del proyecto en el dominio de error?
zrslv
1
@zrxq Es valioso tener diferentes dominios de error con seguridad, pero imagina que escribiste mal tu proyecto o cambiaste tu nombre y quisieras que se reflejara en todas partes. Es mejor configurarlo dinámicamente que codificarlo de forma rígida.
Connor
1
@vare Eso está claro, realmente no entiendo qué beneficios prácticos proporcionaría. Tengo entendido que esos identificadores solo deben ser únicos en el contexto de la aplicación, eso es todo. De acuerdo, tal vez solo quieras que sean más agradables estéticamente, ¡lo entiendo!
zrslv
1
Sí, mencionaste un buen punto. Hay ocasiones en las que desea que el dominio sea único, supongo ... por ejemplo, tal vez si está creando un SDK o (cocoa) Pod, querrá que su dominio de error refleje de dónde vino, no el del proyecto. nombre. EDITAR: Yo también (en mi respuesta) quería señalar que @ "com.myName.myProject" es idéntico al bundleIdentifier en este caso, que la gente podría no saber.
Connor
4

Cómo crear un NSError personalizado:

Primero cree un diccionario del mensaje de error

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

Luego, asigne userInfo al NSDictionary y listo.

Mike Zriel
fuente