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(); }
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.