Back-End

25 jul, 2017

C# – Usando filtros em exceções (exceptions filters)

Publicidade

Neste artigo, vou apresentar as exceptions filters, ou filtros em exceções, o novo recurso da versão 6.0 da linguagem C#.

O recurso exception filters é um novo recurso introduzido na versão C# 6.0 que permite executar blocos try/catch com base em uma condição específica quando ocorre uma exceção.

Nota: Esse recurso já existia no VB .NET.

Isso significa que em um bloco try/cacth, com vários blocos catch, podemos decidir qual bloco catch deverá ser executado segundo um critério pré-definido, especificando uma condição no block catch.

Isso pode ser implementado facilmente adicionando a condição when junto com os blocos catch.

try
{
 // código passível de erro 
}
catch (Exception e) when (Filtro(e))
{
 // acão
}

Por exemplo, no código a seguir, estamos forçando uma exceção fazendo uma divisão por zero, e, definindo duas condições em cada bloco catch.

static void Main(string[] args)
 {
 Console.WriteLine("Forçando uma exceção na divisão por zero");
 int i = 5;
 try
 {
 int a = 0;
 int b = 5;
 int c = b / a;
 }
 catch (Exception) when (i > 5)
 {
 Console.WriteLine("Exceção com condição i > 5");
 }
 catch (Exception) when (i <= 5)
 {
 Console.WriteLine("Exceção com condição i <= 5");
 }
 Console.ReadKey();
 }

C# - Usando Filtros em Exceções (Exceptions Filters)

No primeiro bloco catch definimos que quando ocorrer a exceção ele será executado se o valor de i for maior que 5.

No segundo bloco catch, definimos que ao ocorrer a exceção ele será executado se o valor de i for menor ou igual a 5.

Como o valor de i é igual a 5, temos que o segundo bloco catch será executado. Conforme mostra a figura a lado do código.

Mas não conseguiríamos o mesmo resultado definindo o código para as condições dentro do bloco de captura? É lógico que sim, mas existe uma diferença fundamental.

Se sua condição esta no bloco catch, você esta capturando a exceção e então verificando a condição, enquanto que usando exception filters você esta verificando a condição antes de capturar a exceção.

Se a condição não for satisfeita, o bloco catch será ignorado e o código se move para verificar se existem outros blocos catch que correspondem à exceção. Certo!

Podemos usar esse recurso de diversas formas, como no exemplo a seguir, onde estamos redirecionando para uma página em uma aplicação web:

protected void Page_Load(object sender, EventArgs e) 
 { 
 try 
 { 
 //Chamando uma página que pode não existir 
 Response.Redirect("~/Admin/Login.aspx"); 
 } 
 catch (HttpException hex) if(hex.GetHashCode==400) 
 { 
 lblMessage.Text="Este página não foi encontrada !"; 
 } 
 catch (HttpException hex) if(hex.GetHashCode==500) 
 { 
 lblMessage.Text="Erro interno do servidor !"; 
 } 
 }

Fazendo o tratamento de exceção e usando o exeption filters podemos definir o bloco a ser executado com base no código do erro que gerou a exceção.

Ao usar este recurso, prefira capturar e relançar a exceção pois dessa forma você mantém a pilha intacta. Se posteriormente uma exceção fizer com que a pilha seja despejada, você poderá ver a fonte original dela, em vez de apenas o último local onde o erro ocorreu.