Mais uma olhada no recém lançado Preview 4 do ASP.Net MVC. Se você chegou aqui agora, vale a pena dar uma olhada nos outros posts. Nesse vou dar uma olhada no tratamento de erros, que é feito com um Filter Interceptor. Eu já havia visto o cache com Filter Interceptor, e a implementação do tratamento de erro é também muito simples, seguindo o mesmo modelo de atributos em funções. É mais simples, inclusive, do que era antes com Web Forms. E é bem configurável.

Fiz 2 ações no controlador “Quebrado”: ação Index, que é a padrão (não precisa especificar), não trata o erro, e ação “tratada”, que trata o erro.

Antes, quando você tinha um erro, você recebia a seguinte tela de erro, se tivesse os custom errors desligados (ação Index):

Erro Padrão do ASP.Net com ASP.Net MVC- CustomErrors Off

Se custom errors estiver ligado, a mensagem é a seguinte (ação Index):

Erro Padrão do ASP.Net com ASP.Net MVC- CustomErrors On

Até aí, essa é a resposta padrão do ASP.Net, todos conhecemos a velha tela amarelona (e não gostamos de vê-la, não é verdade?). O ASP.Net MVC traz agora uma novidade: pode-se tratar erros com um simples Interceptor Filter, que é aplicado com um atributo no método (ação do MVC) ou na classe (controlador).

Se a exibição dos erros erros estiver habilitada (custom errors off), e uma ação tiver um erro, a view de erros será exibida, conforme a figura abaixo (note que essa é a ação “tratada”):

Nova View de erros - CustomErrors Off

E se estiver desabilitada (custom errors on), será exibida uma mensagem mais simples, sem o detalhamento do problema (o que é prática comum de segurança) – exibindo ação “tratada”:

Nova View de erros - CustomErrors On

Já se você quiser fazer um tratamento customizado do erro, você pode. Abaixo fiz uma view padrão para mostrar erros de overflow (mais uma vez, ação “tratada”:

View de erros Customizada

Como funciona? Muito simples. Vejam abaixo o código do controller:

    9 public class QuebradoController : Controller

   10 {

   11     public ActionResult Index()

   12     {

   13         return JogaErro();

   14     }

   15

   16     [HandleError(ExceptionType = typeof(OverflowException), View = “OverflowException”)]

   17     [HandleError()]

   18     public ActionResult Tratada()

   19     {

   20         return JogaErro();

   21     }

   22

   23

   24     public ActionResult JogaErro()

   25     {

   26         if (Session[“aleatorio”] == null)

   27             Session[“aleatorio”] = 0;

   28         var aleatorio = (int)Session[“aleatorio”];

   29         aleatorio++;

   30         if (aleatorio > 1)

   31             aleatorio = 0;

   32         Session[“aleatorio”] = aleatorio;

   33

   34         switch (aleatorio)

   35         {

   36             case 0:

   37                 throw new OverflowException(“Essa é uma OverflowException.”);

   38             default:

   39                 throw new ApplicationException(“Essa é uma ApplicationException.”);

   40         }

   41     }

   42 }

A acão “tratada” tem 2 atributos chamados HandleError, que são os atributos que fazem o tratamento. O primeiro informa que trata exceções de overflow, e especifica a View, através de parâmetros, ficando a View de nome “OverflowException” responsável por esses erros. O segundo trata todas as outras exceções, e utiliza a View padrão, que é chamada Errors.aspx, e fica no diretório /Views/Shared. Vejam o Solution Explorer:

Solution explorer

Vejam o código da View:

    7 namespace MvcApplicationErrorHandler1.Views.Shared

    8 {

    9     public partial class Error : ViewPage<HandleErrorInfo>

   10     {

   11     }

   12 }

Ela utiliza como modelo um objeto HandleErrorInfo, que é o seguinte:

    1 namespace System.Web.Mvc

    2 {

    3     public class HandleErrorInfo

    4     {

    5         public HandleErrorInfo(Exception exception, string controller, string action);

    6

    7         public string Action { get; }

    8         public string Controller { get; }

    9         public Exception Exception { get; }

   10     }

   11 }

Esse objeto tem propriedades para a ação, para o controlador, e para a exceção lançada. Minha customizada utiliza esses dados:

    1 <%@ Page Title=”” Language=”C#” MasterPageFile=”~/Views/Shared/Site.Master”

    2 AutoEventWireup=”true” CodeBehind=”OverflowException.aspx.cs”

    3 Inherits=”MvcApplicationErrorHandler1.Views.Quebrado.OverflowException” %>

    4 <asp:Content ID=”Content1″ ContentPlaceHolderID=”MainContent” runat=”server”>

    5     <h2>Você teve uma OverflowException</h2>

    6     <b>Dados:</b><br />

    7     <b>Action:</b>              <% =this.ViewData.Model.Action %><br />

    8     <b>Controller:</b>          <% =this.ViewData.Model.Controller %><br />

    9     <b>Mensagem da exceção:</b> <% =this.ViewData.Model.Exception.Message %><br />

   10 </asp:Content>

E o resultado é a imagem lá em cima.

Achei o resultado muito bom. Dá para tratar erros muito bem. Diferente do AJAX com MVC, já é uma função bem completa. Já imagino uma classe que herde de ViewPage Controller tipo uma ErrorHandlerViewPage ControlleBase, sendo colocada como classe de base, e podendo até já realizar o tratamento de erro. Para o log do erro, imagino que seria com a criação de outro filter interceptor. Vou pensar nisso depois coloco aqui. Alguma sugestão pessoal?

Giovanni Bassi

Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.