2010-10-19 25 views
8

He encontrado preguntas aquí Should a retrieval method return 'null' or throw an exception when it can't produce the return value? y Should functions return null or an empty object?, pero creo que mi caso es bastante diferente.¿Debo devolver nulo o lanzar una excepción?

Estoy escribiendo una aplicación que consiste en un servicio web y un cliente. El servicio web es responsable de acceder a los datos y devolver los datos al cliente. Diseño mi aplicación como esta:

// servicio web

try 
{ 
    DataTable data = GetSomeData(parameter); 
    return data 
} 
catch (OopsException ex) 
{ 
    //write some log here 
    return null; 
} 

// cliente:

DataTable data = CallGetSomeData(parameter); 
    if(data == null) 
    { 
     MessageBox.Show("Oops Exception!"); 
     return; 
    } 

Bueno, hay una regla de no volver nula. No creo que deba volver a lanzar una excepción y dejar que el cliente atrape SoapException. ¿Cuál es tu comentario? ¿Hay un mejor enfoque para resolver este problema?

Gracias.

+0

Las excepciones le permiten [ajustar sus condiciones posteriores] (http://stackoverflow.com/q/1744176/54262). También están estrechamente relacionados con el lenguaje, el estilo y la convención de codificación; pero no has especificado nada de eso. –

+0

Parece que es asp.net, creo? Debe etiquetarlo en consecuencia. – RMorrisey

Respuesta

4

En su caso, una excepción ya ha sido lanzada y manejada de alguna manera en su servicio web.

Volviendo nulo, hay una buena idea porque el código del cliente puede saber que hay un error en su servicio web.

En el caso del cliente, creo que la forma en que la tiene es buena. No creo que haya una razón para lanzar otra excepción (aunque ya no estés en el servicio web).

Lo digo porque, técnicamente, nada ha causado un error en su código de cliente. Acaba de obtener datos erróneos del servicio web. Esto es solo cuestión de manejar entradas potencialmente malas de una fuente externa.

Personalmente, como regla general, evito arrojar excepciones cuando obtengo datos incorrectos ya que el código del cliente no puede controlar eso.

Solo asegúrese de manejar la condición data == null de forma tal que no bloquee su código de cliente.

2

Todos los servicios web que he utilizado devuelven objetos, no tipos de datos simples. Estos objetos generalmente contienen un valor bool llamado Success que le permite probar muy rápidamente si confía o no en los datos devueltos. En cualquier caso, creo que cualquier error arrojado debe ser imposible de traspasar (es decir, no intencional) y, por lo tanto, significa un problema con el servicio en sí.

0

La práctica general en el manejo de excepciones es, cuando la secuencia de flujo se espera en circunstancias normales, ya que la secuencia no se pudo completar debido a la falta de disponibilidad de recursos o entrada esperada.

En su caso, aún necesita decidir cómo desea que reaccione el código del lado del cliente por nulo o por excepción.

0

¿Qué tal pasar un delegado para ser invocado cuando pasa algo malo? El delegado podría lanzar una excepción si eso fuera lo que le gustaría al exterior, o dejar que la función devuelva un valor nulo (si el código externo lo verificará), o posiblemente tomar alguna otra acción. Dependiendo de la información transmitida al delegado, es posible que pueda tratar las condiciones del problema de manera tal que permita que el procesamiento continúe (por ejemplo, el delegado puede establecer un indicador de "reintento" las primeras veces que se llame, en caso de que la red escamosa se esperan conexiones). También es posible que un delegado registre información que no existiría en el momento en que una excepción podría quedar atrapada.

PS - Es probablemente el mejor para pasar una clase personalizada al delegado detectado problemas. Hacer eso permitirá versiones futuras del método para proporcionar información adicional al delegado, sin romper implementaciones que esperan información más simple.

1

Creo que todo se reduce a la pregunta de si su cliente puede o no usar cualquier información de por qué no se devolvieron datos.
Por ejemplo - si no hay datos fue devuelto porque el servidor (SQL decir) que se llama en GetSomeData estaba abajo, y el cliente puede realmente hacer algo con esa información (por ejemplo, mostrar un mensaje apropiado) - usted no desea ocultar esa información - arrojar un error es más informativo.
Otro ejemplo - si parameter es nulo, y que provoca una excepción .. (aunque probablemente debería haber tenido cuidado de que más temprano en el código .. pero se entiende la idea) - debe tener una excepción apropiada (informativo).

Si el cliente no se preocupa en absoluto por qué no se consiguió ninguna datos de nuevo, puede devolver null, que va a ignorar el texto de error de todos modos y es código será el mismo ..

1

Si su cliente y servicio se ejecutan en diferentes máquinas o procesos diferentes, será imposible para arrojar un error del servicio y atraparlo en el cliente. Si insiste en usar excepciones, lo mejor que puede esperar es algún proxy en el cliente para detectar la condición de error (ya sea nula o alguna otra convención) y volver a lanzar una nueva excepción.

0

Se recomiendan excepciones en el mismo espacio de proceso. En todos los procesos, solo a través de la información se evalúa un éxito/fracaso.

2

creo que puede haber algunos factores a tener en cuenta al tomar una decisión:

  • cuál es la forma idiomática de hacer esto en el lenguaje de su uso (si no era un servicio web)
  • lo bueno que su biblioteca de jabón/servicio web es (no se propagan excepciones o no)
  • lo que es lo más fácil para el cliente para hacer

tiendo a hacer que el cliente haga lo más fácil, lo idiomático, dentro de las limitaciones de la biblioteca. Si el cliente lib no se encarga de restaurar automáticamente las excepciones serializadas, probablemente lo envolveré con una lib que lo haga para poder hacer lo siguiente.

Cliente:

try: 
    # Restore Serialized object, rethrow if exception 
    return CallGetSomeData(parameter); 
except Timeout, e: 
    MessageBox.Show("timed out") 
except Exception, e: 
    MessageBox.Show("Unknown error") 
exit(1) 

WebService:

try: 
    return GetSomeData(parameter) # Serialized 
except Exception, e: 
    return e # Serialized 
4

En general trato de diseñar mis servicios web de tal manera que regresan una bandera de algún tipo que indica si hubo un técnico/funcionales error o no , además, trato de devolver un objeto complejo para el resultado no sólo una cadena, de modo que pueda volver cosas como:

result-> Código = "MANTENIMIENTO" result-> MaintenanceTill = "2010-10-29 14: 00:00"

por lo que para un servicio web que me debe obtener una lista de dataEntities voy a devolver algo como:

<result> 
    <result> 
     <Code>OK</Code> 
    </result> 
    <functionalResult> 
     <dataList> 
      <dataEntity>A</dataEntity> 
     </dataList> 
    </functionalResult> 
</result> 

por lo que cada fracaso que puede ocurrir detrás de mi servicio web está escondido en un resultado de error. las únicas excepciones que los desarrolladores deben tener en cuenta al llamar a mi servicio web son las excepciones o errores que pueden ocurrir antes del servicio web.

2

Su primer problema es "una regla de no devolver nulo". Yo recomendaría fuertemente reconsiderar eso.

Devolución de una SoapException es una posibilidad, pero como ya se ha mencionado hacktick, sería mejor para devolver un objeto complejo con un indicador de estado {Éxito, Fallo} con cada respuesta del servicio web.

0
  • Dado que usted es el cliente a su servicio web, puede iniciar sesión excepción en la capa de servicio y devolver NULL para el cliente, sin embargo, el cliente todavía debe saber si el CallGetSomeData un valor nulo porque a) no hay datos disponibles, o b) hay una excepción en la base de datos ya que la tabla está bloqueada. Por lo tanto, siempre es bueno saber qué ha causado el error para facilitar la presentación de informes en el lado del cliente. Debe tener un código de error y una descripción como parte de su mensaje.
  • Si no está consumiendo su servicio web, debe lanzar una excepción por las mismas razones mencionadas anteriormente, el cliente debe saber qué sucedió y depende de ellos decidir qué hacer con eso.
+0

¿Cómo definirías "consumir tu servicio web"? TIA. – AbdullahC

+0

"no consume su servicio web" - "no es un cliente de su servicio". Esto es cuando escribes un servicio de uso público como la autenticación con tarjeta de crédito. – anivas

Cuestiones relacionadas