Pregunta

Estoy teniendo una discusión con un colega acerca de cuándo tirar faltas y cuando no tirar faltas en un servicio WCF.

Una opinión es, que sólo tirar faltas cuando la operación de servicio no podría hacer su trabajo debido a algún error; y algo puede estar en un estado inválido a causa de ella. Así, algunos ejemplos:

  • ValidateMember (nombre de la cadena, cadena contraseña, país cadena) -> lanzaría un fallo si no se pasan los parámetros obligatorios, ya que la validación en sí no podía ser ejecutado; -> echaría la culpa si ocurrió algún error interno, al igual que la base de datos se redujo -> devolvería un contrato estado en todos los demás casos, que especifica el resultado de la validación (MemberValidated, WrongPassword, MemberNotKnown, ...)

  • GetMember (int memberId) -> haría sino echar la culpa si algo se ha reducido, en todos los demás casos, sería volver al miembro o nula si no se encuentra

La otra opinión es que también hay que tirar faltas cuando GetMember no encuentra el miembro, o en el caso de ValidateMember la contraseña es incorrecta.

¿Qué opinas?

¿Fue útil?

Solución

Mi opinión sobre esto ...

Hay tres causas de fallo:

  1. El código de servicio inició una excepción, por ejemplo, error de base de datos, error lógico en el código. Esto es tu culpa.
  2. El código de cliente no hizo uso de su servicio correctamente según su documentación, por ejemplo, que no se estableció un valor de indicador necesario, no pudo pasar de un ID. Esto es culpa del desarrollador de software de cliente.
  3. El usuario final escrito en algo tonto en la pantalla, por ejemplo, fecha de nacimiento, el salario negativo faltante. Esto es culpa del usuario final.

Todo depende de cómo usted elige para asignar contratos de fallos reales a cada causa del fracaso. Por ejemplo, hacemos esto:

  • Para las causas 1 y 2, todas las necesidades de código de cliente para saber es que el servicio no pudo. Se define un contrato muy simple falla "error grave" que contiene sólo un identificador de error único. Todos los detalles del error se registran en el servidor.
  • para la causa 3, las necesidades de los usuarios finales para saber exactamente lo que él / ella hizo mal. Definimos un contrato de fallos "validación de errores" que contiene una colección de mensajes de error para el código de cliente para su visualización en pantalla.

Microsoft EntLib para la causa 3, y el uso de blindaje a mango provoca 1 y 2 declarativa. Se convierte en un código muy simple.

Para aclarar:

manejar las tres causas como esta dentro del servicio:

  1. Una excepción inesperada se lanza en el código de servicio. Nos ponemos al día que en el nivel superior (en realidad excepción de blindaje capturas, pero el principio es el mismo). Registro de todos los detalles, y luego lanzan una FaultException<ServiceFault> al cliente que contiene sólo el ID de error.
  2. validar los datos de entrada y lanzar deliberadamente una excepción. Es normalmente un ArgumentException, pero cualquier tipo apropiado haría. Una vez que se tira, que se trata exactamente de la misma manera que (1) porque queremos hacer que parezca lo mismo para el cliente.
  3. validar los datos de entrada y lanzar deliberadamente una excepción. Esta vez, se trata de un FaultException<ValidationFault>. Configuramos blindaje excepción a pasar éste a través de un-envuelto, por lo que aparece en el cliente como FaultException<ValidationFault> no FaultException<ServiceFault>.

El resultado final:

  • No hay bloques de captura en todo el interior del servicio (código limpio agradable).
  • Sólo cliente tiene que ponerse al FaultException<ValidationFault> si quiere mostrar mensajes al usuario. Todos los demás tipos de excepciones que incluyen FaultException<ServiceFault> son tratados por manejador de errores global del cliente como errores fatales, ya que un error grave en el servicio en general significa un error fatal en el cliente también.

Otros consejos

es un campo común, el fracaso de rutina, a continuación, lanzando un fallo es un error. El software debe ser escrito para manejar los asuntos de rutina, como entrar en una contraseña incorrecta. tratamiento de los fallos es por falta excepcional que no se consideran parte del diseño normal del programa.

Por ejemplo, si el programa fue escrito con la idea de que siempre tiene acceso a una base de datos y la base de datos no es accesible, que es un problema por el que la "solución" es bien fuera de los límites de su software. Un fallo debe ser desechado.

procesamiento de fallos utiliza diferentes flujos lógicos a través de la estructura del lenguaje de programación, y mediante el uso sólo cuando se ha "dejado" el procesamiento normal del problema de programación, que hará que su apalancamiento solución de la función del lenguaje de programación en una manera que parece más natural.

Creo que es una buena práctica para el manejo de errores independiente y manejo de errores. Cualquier caso de error debe ser tratado por su programa - manejo de errores se reserva para condiciones excepcionales. Como guía para la separación de los dos que encontró útil al considerar tales casos hay que recordar que sólo hay tres tipos de error (cuando el manejo de datos y mensajes) y solamente un tipo de fallo. Los tipos de error están relacionados con diferentes tipos de validación:

  1. Validación de mensajes - se puede determinar a partir de los contenidos de los mensajes que los datos son válidos o no válidos.

    Ejemplo:. Contenido que se pretende que sea una fecha de nacimiento - se puede deducir de los datos si es válido o no

  2. validación Contexto - sólo se puede determinar que el contenido no es válido por referencia al mensaje combinado con el estado del sistema.

    Ejemplo:. Una fecha válida de unirse a una empresa es anterior a esa fecha de nacimiento personas

  3. Las mentiras en el sistema - sólo se puede determinar que un mensaje de error cuando se encontraba en un mensaje más tarde vomita una anomalía.

    Ejemplo: Fecha de nacimiento válido almacenado e inspección de los programas de certificado de nacimiento de la persona que esto es incorrecto. Corrección de mentiras en el sistema general requieren fuera de acción del sistema, por ejemplo invocando los recursos legales o disciplinarias.

El sistema debe hacer frente a todas las clases de error -. Aunque en el caso de tres esto puede limitarse a emitir una alerta

Fallos (excepciones) por el contrario sólo tienen una causa - la corrupción de datos (que incluye el truncamiento de datos). no se transmiten parámetros de validación: Ejemplo.

A continuación, el mecanismo apropiado es culpa o el manejo de excepciones - básicamente dar el relevo el problema a alguna otra parte del sistema que es capaz de tratar con ella (por lo que no debería haber un destino final para los fallos no controladas)

En los viejos tiempos solía tener una regla que las excepciones eran sólo para cosas excepcionales e inesperadas. Una de las razones por las que no desee utilizar demasiado en ellos era que el "costo" una gran cantidad de potencia de cálculo.

Pero si utilizar las excepciones que puede reducir la cantidad de código, sin necesidad de una gran cantidad de sentencias if else, simplemente dejar que la burbuja excepción arriba.

Depende de su proyecto. Lo más importante es que no hay un estándar de proyecto y todos lo hacen de la misma manera.

Mi opinión es que las excepciones / fallo se debe lanzar cada vez que lo que se supone que el método para hacerlo no puede ser alcanzado. Así que la lógica de validación nunca debe plantear una excepción, salvo si la validación no se puede hacer (es decir, por razones técnicas), pero nunca solo porque los datos no son válidos (en ese caso devolverá validación de códigos / mensajes o nada ayudan a la persona que llama para corregir el datos).

Ahora el caso GetMember es muy interesante porque se trata de semántica. El nombre del método sugieren que un miembro puede ser recuperada haciendo pasar una id (comparar a un método TryGetMember para exemple). Por supuesto, el método no debe producir la misma excepción si el id es ninguna parte se encuentra o si la base de datos no responde, pero un mal Identificación del pasado de este método es probablemente la señal de que algo va mal en algún lugar antes de esa llamada. Salvo que el usuario puede introducir directamente un miembro-id desde la interfaz, en cuyo caso una validación debe ocurrido antes de llamar al método.

He oído mucho sobre el problema de rendimiento. Acabo de hacer una prueba simple usando C # y trow / catch 1000 excepciones. El tiempo que tomó es 23 ms para 1K Excepciones. Eso es 23µ por excepción. Creo que el rendimiento ya no es el primer argumento aquí excepto si va a recaudar más de 2.000 excepción por segundo, en cuyo caso tendrá un rendimiento de hasta el 5%, lo que puedo empezar a considerar.

Mi humilde opinión ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top