WCF Web API – Tratamento de Erros

O WCF fornece um ponto de estensibilidade que nos permite centralizar o tratamento das exceções que eventualmente acontecem dentro do nosso serviço, e que já tive a oportunidade de falar disso aqui. Basicamente você recorre à uma interface chamada IErrorHandler, que quando acoplado ao runtime do WCF, qualquer exceção disparada será enviada à este handler, dando a oportunidade dele fazer o que achar necessário, incluindo o logging da mesma.

Com o WCF Web API, a Microsoft também está criando um ponto para permitir que se adicione um código customizado para interceptar as exceções que são disparados por estes tipos de serviços. Como já era de se esperar, essa classe implementa a interface IErrorHandler, e mais uma vez, a Microsoft cria “uma classe acima” para abstrair a complexidade do WCF.

Tudo o que precisamos fazer é criar uma classe que herda da classe abstrata HttpErrorHandler, sobrescrevendo os métodos OnHandleError e OnProvideResponse. O primeiro método retorna um valor boleano indicando se deve ou não abortar a sessão, caso exista uma. Já o segundo método, OnProvideResponse, recebe como parâmetro a exceção que foi disparada pelo serviço, e permite customizarmos o retorno para o cliente, como por exemplo, definir um status do HTTP coerente com o problema que ocorreu. O retorno deste método é representado por um objeto do tipo HttpResponseMessage, que define a mensagem que chegará ao cliente que solicitou. Abaixo temos um exemplo desta implementação:

public class BadRequestErrorHandler : HttpErrorHandler
{
    protected override bool OnHandleError(Exception error)
    {
        return true;
    }

    protected override HttpResponseMessage OnProvideResponse(Exception error)
    {
        HttpResponseException exception = error as HttpResponseException;               
        response = exception.Response;
        response.StatusCode = HttpStatusCode.BadRequest;

        return response;
    }
}

Uma vez criado o tratador de erros, precisamos adicioná-lo à execução, e para isso, vamos recorrer ao configurador desta nova API, que é a classe HttpHostConfiguration. Esse classe possui uma interface fluente, expondo um método genérico chamado SetErrorHandler<T>, onde o tipo T deve ser uma classe que herda de HttpErrorHandler.

protected void Application_Start()
{
    var config =
        HttpHostConfiguration.Create()
            .SetResourceFactory<MEFResourceFactory>()
            .SetErrorHandler<BadRequestErrorHandler>();

    RouteTable.Routes.MapServiceRoute<ServicoDeProspeccao>(“prospeccoes”, config);
}

Finalmente, o que precisamos fazer dentro do serviço quando há algum problema, é disparar uma exceção do tipo HttpResponseException, que por sua vez, retrata uma falha que houve durante a execução do mesmo.