2008-10-13 11 views
15

¿Cuáles son las pautas para cuándo crear un nuevo tipo de excepción en lugar de usar una de las excepciones integradas en .Net?Cuándo usar una nueva excepción escriba

El problema que me hizo pensar es esto. Tengo un servicio WCF, que es un servicio básico de entrada-salida. Si el servicio no puede crear una salida, porque la entrada no es válida, quiero lanzar una excepción, pero ¿cuál?

Ahora mismo estoy lanzando system.Exception, pero esto no me parece bien, no sé por qué, simplemente se siente mal. Una cosa que me molesta, si la pruebo con una prueba de unidad y espero que el sistema sea lanzado. La excepción también podría ser arrojada por el marco u otro código y no por el código que exceptué para arrojar. La prueba luego pasaría, ya que recibo la excepción esperada, pero debería haber fallado.

¿Qué me recomiendas?

+0

Creo que esto es adecuado para todos los idiomas con excepciones. –

Respuesta

15

Evite arrojar System.Exception o System.ApplicationException usted mismo, ya que son demasiado generales.

Para los servicios de WCF hay Contratos de falla: una excepción genérica que puede indicar a los subscriptores que deben manejar.

bandera de la interfaz con:

[FaultContract(typeof(LogInFault))] 
void LogIn(string userName, string password, bool auditLogin); 

Entonces, si hay una excepción que puede lanzar esta falla específica:

throw new FaultException<LogInFault>(new LogInFault(), "message"); 

Uso del [DataContract] serialización en su defecto - esto le evita tener que maneja todas las excepciones de serialización que normalmente se requieren.

+1

@ Keith: esto es bueno. Para que sea aún mejor, proporcione un ejemplo de LoginFault. – RichardOD

7

Definitivamente evite arrojar System.Exception para cualquier cosa que no sea un código desechable.

Si un argumento para un método no es válido, ejecute ArgumentException (o alguna excepción derivada más específica). Consulte los documentos para conocer las excepciones existentes antes de crear las suyas, pero a menudo puede ser útil hacerlo. (Por supuesto, puede derivar su propio tipo de excepción de ArgumentException; si tiene algún tipo particular de condición que desea indicar desde varios lugares, la creación de un nuevo tipo proporciona más información que solo ponerla en el mensaje de error).)

Ahora el manejo de errores en WCF bien puede ser diferente al manejo de errores dentro del marco "normal" - sugiero que consulte los documentos/documentos específicos de WCF para eso.

+0

Al usar WCF, generalmente desea distinguir las excepciones que se deben a la entrada del cliente (remitente) de las debidas a un problema/error del servidor. ArgumentException es demasiado general; es mejor utilizar un FaultContract. – Joe

0

Crea siempre un nuevo tipo de excepción (o utiliza un tipo estándar si te conviene).

En ese caso, puede manejar las excepciones como un grupo.

2

No es una buena idea lanzar System.Exception. La razón principal de esto es el efecto que tiene en el código de llamada. ¿Cómo deberían manejar la excepción? Si el código de llamada va a manejar la excepción, entonces tienen que atrapar todas las excepciones, lo que probablemente no sea lo mejor para ellos.

Si una de las excepciones estándar no cubre una circunstancia, debe crear un nuevo objeto Exception si la excepción es algo que el código de llamada debería manejar como un caso especial.

2

System.Exception solo debe usarse como una clase base para Excepciones, nunca se debe lanzar directamente.

El Marco ya ofrece una gran cantidad de clases de excepción válida como ArgumentException, ArgumentNullException, InvalidOperationException, FormatException, OverflowException, etc ...

Usted dice que está haciendo las cosas de E/S, por lo que una buena idea es buscar en operaciones similares en el marco (como int.Parse) y arroje las mismas excepciones para errores similares.

O derive su propia clase de excepción de una clase de excepción existente si ninguna de ellas realmente se ajusta a sus necesidades.

1

¿Cuáles son las pautas sobre cuándo crear una nueva excepción en lugar de escribir usando una de las excepciones incorporadas en .Net?

Cuando no existe una clase de excepción predefinida adecuada.
.NET FW es muy rico, a menudo puede encontrar excepciones predefinidas.

Si el servicio no puede crear una salida , debido a que la entrada no es válida

ArgumentException Class (System)

La excepción que se produce cuando uno de los argumentos presentados a un método no es válido.

0

Como han indicado los carteles anteriores, no deberías estar lanzando System.Exception. De hecho, si ejecuta FxCop en su código, marcaría eso como una violación de regla.

Es recomendable tener un vistazo a Capítulo 18 de Programación Aplicada de .NET Framework, o el capítulo 19 de la CLR más reciente a través de C# (2ª edición) para una guía detallada. Richter hace un excelente trabajo al corregir los conceptos erróneos que muchos desarrolladores tienen acerca de las excepciones.

Ambos libros contienen una lista de las excepciones definidas por la Biblioteca de clases de Framework. Mire la lista y descubra las excepciones más específicas posibles que su código puede arrojar. Si puede recuperarse de una excepción, hágalo en ese bloque catch. Si necesita bloques de captura múltiples, organícelos desde el más específico al menos específico. Cree una excepción personalizada si no puede encontrar una en la lista existente que se adapte a la situación.

2

Si lanza System.Exception, la persona que llama debe atrapar System.Exception. Ambos lados de esto son un no-no, ya que nos deja diciéndole al usuario "que no funcionó", en lugar de algo más útil.

Una excepción ArgumentException es útil si la persona que llama pasó un argumento no válido. Si su función tiene un parámetro int que necesita que sea un número par, entonces usted lanzaría y ArgumentException diciendo a la persona que llamó qué parámetro no era válido y por qué. Sin embargo, si todos los argumentos son válidos pero aún existe un problema, probablemente necesite una excepción personalizada. De esta manera, la persona que llama puede decirle al usuario excatly qué salió mal.

La prueba para mí es realmente del lado de la llamada. Si tuviera una docena de capturas que hicieran lo mismo, realmente solo necesitaría una excepción. Sin embargo, si tuviera una captura y tuviera una declaración que le dijera al usuario que una de las tres cosas salió mal, entonces realmente necesitaba tres excepciones únicas.

Cuestiones relacionadas