Tratamento de Erros e Instâncias


Uma das opções que temos para interceptar os problemas (exceções) que ocorrem dentro das operações de um serviço WCF, é a possibilidade de criar um error-handler, qual acoplamos à execução utilizando um behavior de nível de serviço. A finalidade deste handler é centralizar todo o processo de tratamento de erros, incluindo o procedimento de “tradução” da exceção em faults, e eventuais tarefas de logging.

Um artigo que escrevi há algum tempo, já detalha como criar o error-handler e o behavior para acoplá-lo à execução, mas para recapitular, o principal elemento é a interface IErrorHandler, que deve ser implementada, e mais tarde, acoplada à execução através da interface IServiceBehavior, que através do método ApplyDispatchBehavior, fornece um parâmetro do tipo ServiceHostBase, que com ele chegamos até o ChannelDispatcher, que finalmente expõe uma propriedade chamada ErrorHandlers, que é uma coleção de elementos do tipo IErrorHandler.

Como podemos perceber, o fato de ser uma coleção, podemos adicionar quantas instâncias de classes que implementam a interface IErrorHandler quisermos. Isso nos permite criar um conjunto destas classes, onde cada uma delas analisam/tratam o erro que aconteceu, permitindo isolar em cada implementação um tratamento específico, e incorporando à execução somente aquelas que são necessárias para atender aquele serviço.

internal class TratadorDeErros01 : IErrorHandler { }

internal class TratadorDeErros02 : IErrorHandler { }

internal class TratadorDeErros03 : IErrorHandler { }

Um dos métodos expostos pela interface IErrorHandler é o HandleError, que recebe como parâmetro a exceção que foi disparada pelo serviço, e retorna um valor boleano indicando se aquele erro foi ou não tratado da forma esperada por aquele tratador, e dependendo do que retornamos e como está configurado nosso serviço, influenciará drasticamente no comportamento do mesmo, em outras palavras, poderá afetar a instância da classe que representa o serviço.

Partimos do princípio que o nosso serviço esteja configurado com o modelo de gerenciamento de instância como PerSession, e há uma sessão criada. Se você tem vários tratadores acoplados à execução, como por exemplo, os três que criamos acima, eles serão disparados na ordem em que eles foram adicionados à coleção, caso uma exceção não tratada seja disparada no interior da operação que o cliente solicitou. Suponha que o segundo tratador seja capaz de entender o que representa aquela exceção e sabe como lidar com ela. Isso fará com o retorno do método HandleError seja definido como True e, consequentemente, a instância da classe que representa o serviço será mantida ativa, assim como podemos perceber através da imagem abaixo:

Tendo, no mínimo, um tratador que consiga lidar com a exceção disparada, é o suficiente para manter o serviço ativo. Agora, supondo que nenhum dos três tratadores sejam capazes de entender e tratar aquela execeção (todos os métodos HandleError retornarão False), e tendo o mesmo cenário acima, ou seja, um serviço configurado como PerSession, a instância da classe que representa o serviço será abortada, o que obrigará uma nova classe ser criada para atender aquele cliente, perdendo assim eventuais informações de estado que aquela instância mantenha. A imagem abaixo ilustra o que acabamos de ver:

Esse comportamento se deve ao fato de que uma exceção não tratada, por padrão, é entendida pelo runtime de que o serviço (instância) pode ter ficado em um estado falho, o que obriga ao WCF eliminar essa classe, a menos que você altere esse comportamento recorrendo ao recurso que vimos neste artigo.

Para finalizar, tudo o que vimos aqui serve apenas para quando utilizamos o modelo de gerenciamento de instância como PerSession. Para PerCall é indiferente, já que a instância da classe que representa o serviço serve apenas para atender a requisição corrente, e logo em seguida, é descartada. No modelo Single, tudo o que vimos aqui também não importa, já que temos uma única instância atendendo à todos os clientes, e qualquer erro não tratado não é suficiente para descartar a instância do serviço.

Anúncios

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