Envío y recepción de errores
Los errores de SOAP transportan información de condición de errores desde un servicio a un cliente y, en caso de comunicación dúplex, desde un cliente a un servicio de manera interoperable. Normalmente, un servicio define el contenido del error personalizado y especifica qué operaciones pueden devolverlos. (Para obtener más información, vea Definición y especificación de errores). Este tema discute cómo un servicio o cliente dúplex puede enviar esos errores cuando la condición de error correspondiente se ha producido y cómo una aplicación de cliente o servicio administra estos errores. Para obtener información general de control de errores en aplicaciones Windows Communication Foundation (WCF), vea Especificación y administración de errores en contratos y servicios.
Envío de errores SOAP
Los errores de SOAP declarados son aquellos en los que una operación tiene System.ServiceModel.FaultContractAttribute que especifica un tipo de error de SOAP personalizado. Los errores de SOAP no declarados son aquellos que no se especifican en el contrato para una operación.
Envío de errores declarados
Para enviar un error de SOAP declarado, detecte la condición de error para la que el error de SOAP es adecuado y genere una nueva System.ServiceModel.FaultException, donde el parámetro de tipo es un nuevo objeto del tipo especificado en FaultContractAttribute para esa operación. El ejemplo de código siguiente muestra el uso de FaultContractAttribute para especificar que la operación SampleMethod
puede devolver un error de SOAP con el tipo de detalle de GreetingFault
.
Para transportar la información de error GreetingFault
al cliente, detecte la condición de error adecuada y genere una nueva System.ServiceModel.FaultException de tipo GreetingFault
con un nuevo objeto GreetingFault
como el argumento, como en el ejemplo de código siguiente. Si el cliente es una aplicación cliente de WCF, experimenta esto como una excepción administrada donde el tipo es System.ServiceModel.FaultException de tipo GreetingFault
.
Envío de errores no declarados
Enviar errores no declarados puede ser muy útil para diagnosticar y depurar rápidamente los problemas en las aplicaciones de WCF, pero su utilidad como herramienta de depuración es limitada. Más generalmente, se recomienda al depurar que utilice la propiedad System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults. Al establecer este valor en true, los clientes experimentan tales errores como excepciones FaultException de tipo ExceptionDetail.
Nota
Dado que las excepciones administradas pueden exponer información interna de la aplicación, establecer System.ServiceModel.ServiceBehaviorAttribute.IncludeExceptionDetailInFaults o System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults en true puede permitir que los clientes WCF obtengan información sobre las excepciones de operaciones de servicio internas, incluida la información de identificación personal u otro tipo de información confidencial.
Por consiguiente, establecer System.ServiceModel.ServiceBehaviorAttribute.IncludeExceptionDetailInFaults o System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults en true sólo está recomendado como una manera de depurar temporalmente una aplicación de servicio. Además, el WSDL para un método que devuelve excepciones administradas no controladas de esta manera no contiene el contrato para la FaultException de tipo ExceptionDetail. Los clientes deben esperar la posibilidad de se produzca un error de SOAP desconocido (se devuelve a los clientes WCF como objetos System.ServiceModel.FaultException) para obtener correctamente la información de depuración.Para enviar un error de SOAP no declarado, genere un objeto de System.ServiceModel.FaultException (esto es, no del tipo genérico FaultException) y pase la cadena al constructor. Esto se expone a las aplicaciones cliente de WCF como una excepción System.ServiceModel.FaultException generada donde la cadena está disponible llamando al método System.ServiceModel.FaultException.ToString.
Nota
Si declara un error de SOAP de tipo cadena y, a continuación, lo genera en su servicio como una FaultException donde el tipo del parámetro es una System.String, el valor de la cadena está asignado a la propiedad System.ServiceModel.FaultException.Detail, y no está disponible desde System.ServiceModel.FaultException.ToString.
Control de errores
En clientes WCF, los errores de SOAP que se producen durante la comunicación que son de interés para las aplicaciones cliente se elevan como excepciones administradas. Aunque hay muchas excepciones que pueden producirse durante la ejecución de cualquier programa, las aplicaciones que usan el modelo de programación de cliente de WCF pueden esperar administrar excepciones de uno de los dos tipos siguientes como resultado de la comunicación.
Los objetos TimeoutException se producen cuando una operación supera el período de tiempo de espera especificado.
Los objetos CommunicationException se producen cuando hay alguna condición de error de comunicación recuperable en el servicio o el cliente.
La clase CommunicationException tiene dos tipos derivados importantes: FaultException y el tipo FaultException genérico
Las excepciones FaultException se producen cuando un agente de escucha recibe un error que no se espera o especifica en el contrato de operación; normalmente esto sucede cuando se depura la aplicación y el servicio tiene la propiedad System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults establecida en true.
Las excepciones FaultException se producen en el cliente cuando se recibe un error de SOAP especificado en el contrato de la operación en respuesta a una operación bidireccional (es decir, un método con un atributo OperationContractAttribute con IsOneWay establecido en false).
Nota
Cuando un servicio de WCF tiene la propiedad System.ServiceModel.ServiceBehaviorAttribute.IncludeExceptionDetailInFaults o System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults establecida en true, el cliente experimenta esto como una FaultException no declarada de tipo ExceptionDetail. Los clientes pueden detectar este error concreto o administrar el error en un bloque de detección de FaultException.
Normalmente, sólo las excepciones FaultException, TimeoutException y CommunicationException son de interés para los clientes y servicios.
Nota
Por supuesto, se producen otras excepciones. Entre las excepciones no esperadas se incluyen errores catastróficos como System.OutOfMemoryException; normalmente las aplicaciones no deberían detectar ese tipo de métodos.
Detectar excepciones de errores en el orden correcto
Puesto que FaultException deriva de FaultException, y FaultException deriva de CommunicationException, es importante detectar estas excepciones en el orden apropiado. Por ejemplo, si tiene un bloque de intento/detección en el que primero detecta CommunicationException, todos los errores SOAP especificados y no especificados se administran ahí; los bloques de detección posteriores para administrar una excepción FaultException personalizada nunca se invocan.
Recuerde que una operación puede devolver un número indefinido de errores especificados. Cada error es de un tipo único y se ha de administrar separadamente.
Administre las excepciones al cerrar el canal
La mayor parte de la discusión anterior tiene que ver con los errores enviados en el curso del procesamiento de mensajes de aplicaciones, es decir, mensajes enviados explícitamente por el cliente cuando la aplicación de cliente llama a las operaciones en el objeto de cliente de WCF.
Incluso con la disposición de objetos locales, el objeto puede elevar o enmascara excepciones que tienen lugar durante el proceso de reciclaje. Algo similar puede producirse al utilizar objetos de cliente de WCF. Al llamar a operaciones, está enviando mensajes a través de una conexión establecida. Cerrar el canal puede producir excepciones si la conexión no se puede cerrar limpiamente o ya está cerrada, aun cuando todas las operaciones hayan devuelto correctamente.
Normalmente, los canales de objeto de cliente se cierran de una de las siguientes maneras:
- Cuando se recicla el objeto de cliente de WCF.
- Cuando la aplicación de cliente llama System.ServiceModel.ClientBase.Close.
- Cuando la aplicación de cliente llama System.ServiceModel.ICommunicationObject.Close.
- Cuando la aplicación de cliente llama a una operación que es una operación de finalización para una sesión.
En todos los casos, cerrar el canal indica al canal que comience a cerrar todos los canales subyacentes que puedan estar enviando mensajes para admitir una funcionalidad compleja en el nivel de la aplicación. Por ejemplo, cuando un contrato requiere sesiones, un enlace intenta establecer una sesión mediante el intercambio de mensajes con el canal del servicio hasta que se establezca una sesión. Cuando se cierre el canal, el canal de la sesión subyacente notifica al servicio que la sesión se ha terminado. En este caso, si el canal ya se ha anulado, cerrado o es inutilizable (por ejemplo, cuando se desconecta un cable de red), el canal de cliente no puede informar al canal del servicio que se finaliza la sesión y es posible que se produzca una excepción.
Anule el canal si fuese necesario
Dado que cerrar el canal también puede producir excepciones, se recomienda que además de detectar las excepciones de error en el orden correcto, es importante anular el canal que se utilizó para realizar la llamada en el bloque de detección.
Si el error transporta información de error específica de una operación y sigue siendo posible que otros puedan utilizarla, no hay ninguna necesidad de anular el canal (aunque estos casos son aislados). En el resto de casos, se recomienda que anule el canal. Para obtener un ejemplo que demuestra todos estos puntos, vea Expected Exceptions.
El siguiente ejemplo de código muestra cómo administrar las excepciones de errores de SOAP en una aplicación de cliente básica, incluyendo un error declarado y uno no declarado.
Nota
Este código de ejemplo no utiliza la construcción using. Dado que el cierre de canales puede producir excepciones, se recomienda que las aplicaciones creen primero un cliente de WCF, y, a continuación, abran, utilicen y cierren el cliente de WCF en el mismo bloque de intento. Para obtener información detallada, consulte Introducción a un cliente WCF y Avoiding Problems with the Using Statement.
Consulte también
Referencia
FaultException
FaultException
System.ServiceModel.CommunicationException
Otros recursos
Expected Exceptions
Avoiding Problems with the Using Statement