Ampliando o controle sobre o tratamento de erros e relatórios
O exemplo ErrorHandling demonstra como estender o controle sobre o tratamento de erros e relatório de erros em um serviço Windows Communication Foundation (WCF) usando a IErrorHandler interface. O exemplo é baseado na Introdução com algum código adicional adicionado ao serviço para lidar com erros. O cliente força várias condições de erro. O serviço interceta os erros e os registra em um arquivo.
Nota
O procedimento de configuração e as instruções de compilação para este exemplo estão localizados no final deste tópico.
Os serviços podem intercetar erros, executar processamento e afetar como os erros são relatados usando a IErrorHandler interface. A interface tem dois métodos que podem ser implementados: ProvideFault(Exception, MessageVersion, Message) e HandleError. O ProvideFault(Exception, MessageVersion, Message) método permite adicionar, modificar ou suprimir uma mensagem de falha gerada em resposta a uma exceção. O HandleError método permite que o processamento de erros ocorra no caso de um erro e controla se o tratamento de erros adicionais pode ser executado.
Neste exemplo, o CalculatorErrorHandler
tipo implementa a IErrorHandler interface. No
HandleError método, o CalculatorErrorHandler
grava um log do erro em um arquivo de texto Error.txt em C:\Logs. Observe que o exemplo registra a falha e não a suprime, permitindo que ela seja relatada de volta ao cliente.
public class CalculatorErrorHandler : IErrorHandler
{
// Provide a fault. The Message fault parameter can be replaced, or set to
// null to suppress reporting a fault.
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
}
// HandleError. Log an error, then allow the error to be handled as usual.
// Return true if the error is considered as already handled
public bool HandleError(Exception error)
{
using (TextWriter tw = File.AppendText(@"c:\logs\error.txt"))
{
if (error != null)
{
tw.WriteLine("Exception: " + error.GetType().Name + " - " + error.Message);
}
tw.Close();
}
return true;
}
}
O ErrorBehaviorAttribute
existe como um mecanismo para registrar um manipulador de erros com um serviço. Este atributo usa um único parâmetro type. Esse tipo deve implementar a IErrorHandler interface e deve ter um construtor público e vazio. Em seguida, o atributo instancia uma instância desse tipo de manipulador de erros e a instala no serviço. Ele faz isso implementando a IServiceBehavior interface e, em seguida, usando o ApplyDispatchBehavior método para adicionar instâncias do manipulador de erros ao serviço.
// This attribute can be used to install a custom error handler for a service.
public class ErrorBehaviorAttribute : Attribute, IServiceBehavior
{
Type errorHandlerType;
public ErrorBehaviorAttribute(Type errorHandlerType)
{
this.errorHandlerType = errorHandlerType;
}
void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
{
}
void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
{
}
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
{
IErrorHandler errorHandler;
try
{
errorHandler = (IErrorHandler)Activator.CreateInstance(errorHandlerType);
}
catch (MissingMethodException e)
{
throw new ArgumentException("The errorHandlerType specified in the ErrorBehaviorAttribute constructor must have a public empty constructor.", e);
}
catch (InvalidCastException e)
{
throw new ArgumentException("The errorHandlerType specified in the ErrorBehaviorAttribute constructor must implement System.ServiceModel.Dispatcher.IErrorHandler.", e);
}
foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
channelDispatcher.ErrorHandlers.Add(errorHandler);
}
}
}
O exemplo implementa um serviço de calculadora. O cliente deliberadamente faz com que dois erros ocorram no serviço, fornecendo parâmetros com valores ilegais. O CalculatorErrorHandler
usa a IErrorHandler interface para registrar os erros em um arquivo local e, em seguida, permite que eles sejam relatados de volta ao cliente. O cliente força uma divisão por zero e uma condição de argumento fora do intervalo.
try
{
Console.WriteLine("Forcing an error in Divide");
// Call the Divide service operation - trigger a divide by 0 error.
value1 = 22;
value2 = 0;
result = proxy.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
}
catch (FaultException e)
{
Console.WriteLine("FaultException: " + e.GetType().Name + " - " + e.Message);
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.GetType().Name + " - " + e.Message);
}
Quando você executa o exemplo, as solicitações de operação e as respostas são exibidas na janela do console do cliente. Você vê a divisão por zero e as condições de argumento fora do intervalo sendo relatadas como falhas. Pressione ENTER na janela do cliente para desligar o cliente.
Add(15,3) = 18
Subtract(145,76) = 69
Multiply(9,81) = 729
Forcing an error in Divide
FaultException: FaultException - Invalid Argument: The second argument must not be zero.
Forcing an error in Factorial
FaultException: FaultException - Invalid Argument: The argument must be greater than zero.
Press <ENTER> to terminate client.
O arquivo c:\logs\errors.txt contém as informações registradas sobre os erros pelo serviço. Observe que, para o serviço gravar no diretório, você deve certificar-se de que o processo sob o qual o serviço está sendo executado (normalmente ASP.NET ou Serviço de Rede) tem permissão para gravar no diretório.
Fault: Reason = Invalid Argument: The second argument must not be zero.
Fault: Reason = Invalid Argument: The argument must be greater than zero.
Para configurar, compilar e executar o exemplo
Certifique-se de ter executado o procedimento de instalação única para os exemplos do Windows Communication Foundation.
Para criar a solução, siga as instruções em Criando os exemplos do Windows Communication Foundation.
Certifique-se de ter criado o diretório c:\logs para o arquivo error.txt. Ou modifique o nome do arquivo usado no
CalculatorErrorHandler.HandleError
.Para executar o exemplo em uma configuração de máquina única ou cruzada, siga as instruções em Executando os exemplos do Windows Communication Foundation.