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.

Anúncios

2 comentários sobre “WCF Web API – Tratamento de Erros

  1. Boas Michel,

    1 – O método OnHandleError é retornado depois que a resposta já foi enviada para o cliente. Você encontra maiores detalhes aqui: http://www.israelaece.com/post/Tratamento-de-Erros-e-Instancias.aspx
    2 – Devemos utilizar sempre HttpResponseException, porque por padrão, há um error-handler que é adicionado à execução chamado HttpResponseErrorHandler, que está alterando o comportamento esperado. Mas, segundo o Glenn, isso é um bug e está sendo discutido aqui: http://wcf.codeplex.com/discussions/254817. Talvez a próxima versão já esteja com o bug corrigido.
    3 – Olhando superficialmente a API, você pode sim configurar como se fosse um serviço normal, incluindo o endpoint (ABC) e definindo o binding como HttpBinding.

    • Olá Israel! Algumas dúvidas:
      1 – Se eu retornar false no OnHandleError , o que acontece com a execução corrente ?
      2 – Tenho sempre que gerar exceções do tipo "HttpResponseMessage" ? E se acontecer um erro do tipo "divisão por zero" , por exemplo. Ainda sim minha classe irá receber esta exceção ?
      3 – Tenho como fazer a configuração utilizando o Web.Config ao invés do Global.asax?

      Desde já grato pelas respostas!

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s