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):
Se custom errors estiver ligado, a mensagem é a seguinte (ação Index):
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”):
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”:
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”:
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:

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?