ASP .NET - Tratamento de erro a nível da aplicação


O tratamento de erros é fundamental em qualquer aplicação e neste artigo veremos como tratar e registrar os erros em um local comum, independente de onde eles ocorram, em uma aplicação ASP .NET.

Para efetuar o tratamento a nível de aplicação você deve usar o evento Application_Error no arquivo Global.asax; este evento ocorre para qualquer exceção não tratada na aplicação.

Podemos realizar esta tarefa cumprindo as seguintes etapas:

  1. Criar um tratamento para o evento Page_Error
  2. Relançar as páginas de erros a partir dos métodos
  3. Criar um tratamento para o evento Application_Error
  4. Criar uma mensagem detalhada e escrevê-la no log de eventos
  5. Redirecionar o usuário para a página de erro usando Server.Transfer

Resumindo: você vai ter que Incorporar o tratamento de erros nos métodos; adicionar código ao manipulador de eventos Page_Error para relançar os erros de página; adicionar o código para o manipulador de eventos Application_Error no arquivo Global.asax e finalmente criar uma mensagem detalhada e executar o seu registro fazendo o redirecionamento usando Server.Transfer.

O modelo de tratamento de exceções na plataforma ASP.NET fornece a capacidade para tratar as exceções em qualquer nível, desde o nível de método até o nível de aplicação.

Uma exceção não tratada é sequencialmente relançada para cada método na pilha de chamadas. Se nenhum método na pilha de chamadas tratar a exceção, o evento Page_Error será gerado.

Se a exceção não é tratada no evento Page_Error, o evento será relançado e o evento Application_Error é disparado. O relançamento de exceções ao nível de aplicação permite o processamento em um único local da a aplicação.

Para processar erros no nível de aplicação, cada página deve incluir o manipulador de eventos Page_Error com uma única linha de código para relançar a última exceção que ocorreu. Exemplo:

Private Sub Page_Error(ByVal sender As Object,ByVal e As System.EventArgs) Handles MyBase.Error
    'relanca o ulimo erro ocorrido
    Throw Server.GetLastError( )
End Sub 
private void Page_Error(Object sender,System.EventArgs e)
{
   //relança o último erro ocorrido
   throw Server.GetLastError( );
} 
VB .NET C#

Fazemos essa etapa para evitar as informações das exceções envolvidas com uma exceção HttpUnhandledException. A ASP.NET cria automaticamente uma nova HttpUnhandledException no nível da página, a menos que você relance a última exceção, que a partir da perspectiva da ASP.NET constitui uma manipulação de exceção.

Esta é uma das formas de tratar este problema e você não é obrigado a seguir este caminho.

O tratamento de erro para a aplicação é colocado no manipulador de eventos Application_Error(no arquivo global.asax).O primeiro passo é obter uma referência para a última exceção que ocorreu. Exemplo:


UltimaException = Server.GetLastError()
UltimaException = Server.GetLastError();
VB .NET C#

O próximo passo é a criação de uma mensagem detalhada para inserir no registro de eventos. Esta mensagem deve conter a mensagem da exceção mais recente e uma relação completa de todas as informações de erro na lista de links de exceções. A relação completa é obtida chamando o método ToString da última exceção, como no seguinte exemplo de código:


msg = UltimaException.Message &  vbCrLf & vbCrLf & UltimaException.ToString()
msg = UltimaException.Message + "\r\r" + UltimaException.ToString();
VB .NET C#

Em seguida, você pode escrever a mensagem no log de eventos e isto é feito através da criação de um novo objeto EventLog, definindo a propriedade de origem para uma constante contendo o nome da fonte de evento para gravar as informações (log do Aplicativo no nosso exemplo) , e escrever a mensagem no log de eventos.

Ao escrever a entrada no log de eventos, o tipo de evento pode ser definido como Error, FailureAudit, information, SuccessAudit e Warning, todos os quais são membros da enumeração EventLogEntryType. A seguir temos o código que escreve o log de eventos no nosso exemplo :

Log = New EventLog
Log.Source = EVENT_LOG_NAME
Log.WriteEntry(msg,EventLogEntryType.Error)
log = new EventLog();
log.Source = EVENT_LOG_NAME;
log.WriteEntry(msg,EventLogEntryType.Error);
VB .NET C#

O passo final para o processamento dos erros a nível de aplicativo é limpar o erro e redirecionar o usuário para a página onde uma mensagem de erro será exibida segundo este código:


Server.ClearError( )
Server.Transfer("ExibeErroVB.aspx" & "?PageHeader=Erro  Ocorrido" & _
     	  	"&Mensagem1=" & UltimaException.Message & _
		       "&Mensagem2=" & _
       		"Este erro foi processado a nível de Aplicação")
Server.ClearError( );
Server.Transfer("ExibeErroCS.aspx" +
		"?PageHeader=Erro Ocorrido" +
		"&Mensagem1=" + UltimaException.Message +
		"&Mensagem2=" +
		"Este erro foi processado a nível de Aplicação");
VB .NET C#

Se você não limpar o erro, o ASP.NET irá assumir que erro não foi processado e vai lidar com isso para você com sua infame "tela amarela" de erros.

Você pode usar um dos dois métodos abaixo para redirecionar o usuário para a página de erro:

  1. O primeiro método é chamar Response.Redirect, que funciona através do envio de informações para o navegador, instruindo o navegador para fazer um redirecionamento para a página indicada. Isso resulta em uma viagem adicional para o servidor.
  2. O segundo método é Server.Transfer, que é o método que escolhemos, porque transfere o pedido para a página indicada, sem o a viagem adicional ao servidor .

Você pode fazer com que os erros de sua aplicação sejam mais fáceis de serem encontrados no visualizador de eventos, criando uma fonte de evento específico para sua aplicação.

Você não pode criar uma nova fonte de eventos dentro de sua aplicação ASP.NET usando o editor de registro e adicionando uma nova chave para a pasta:
\System\CurrentControlSet\ HKEY_LOCAL_MACHINE Services\EventLog ou criando um aplicativo console para fazer o trabalho para você (esta última opção é mais fácil).

Usando a segunda opção crie um aplicativo console, adicione o código a seguir a ele, e execute o aplicativo. Isto irá criar uma fonte de eventos específico para sua aplicação. A única alteração necessária para o código descrito aqui é para alterar o valor da constante EVENT_LOG_NAME para o nome de sua nova fonte de eventos.

Const EVENT_LOG_NAME As String = "Sua Aplicação"

if (Not EventLog.SourceExists(EVENT_LOG_NAME)) Then
  EventLog.CreateEventSource(EVENT_LOG_NAME, EVENT_LOG_NAME)
End If
const String EVENT_LOG_NAME = "Sua aplicação";
	
if (EventLog.SourceExists(EVENT_LOG_NAME) != null)
{
	EventLog.CreateEventSource(EVENT_LOG_NAME, EVENT_LOG_NAME);
}
VB .NET C#

O código completo para do evento Application_Error no arquivo Global.asax é dado a seguir:

Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
	Const EVENT_LOG_NAME As String = "Sua Aplicação"
	
	Dim lastException As Exception
	Dim Log As EventLog
	Dim msg As String

	'pega o ultimo erro ocorrido
	UltimaException = Server.GetLastError()

	'cria a mensagem de erro a partir da mensagem na ultima exceção
	'com uma relação completa de exceções internas
	msg = UltimaException.Message & _
	          vbCrLf & vbCrLf & _
    	          UltimaException.ToString()

	'Insere a informação do erro no log de eventos
	Log = New EventLog
	Log.Source = EVENT_LOG_NAME
	Log.WriteEntry(msg, EventLogEntryType.Error)

	'limpa o erro e redireciona a pagina usada para exibir a informação de erro
	Server.ClearError()
	Server.Transfer("ExibeErroVB.aspx" & _
	          		"?PageHeader=Erro Ocorrido" & _ 
	    	       	"&Mensagem1=" & UltimaException.Message & _
	  		        "&Mensagem2=" &_
                   			"Este erro foi processado a nível de Aplicação")
End Sub 

Na entrada do log de eventos podemos ver o seguinte padrão de mensagens:

System.NullReferenceException: {"Object reference not set to an instance
of an object."}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: Nothing
HResult: -2147467261
InnerException: Nothing
IsTransient: False
Message: "Object reference not set to an instance of an object."
Source: "App_Web_23987dfhdty"
StackTrace: " at Macoratti.VBExemplo.
CH08ApplicationLevelErrorHandlingVB.Page_Error(Object sender, EventArgs e)
in E:\Macoratti\projects\MacorattiASPNET\
ApplicationLevelErrorHandlingVB.aspx.vb:line 41
at System.Web.UI.TemplateControl.OnError(EventArgs e)
at System.Web.UI.Page.HandleError(Exception e)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint,
Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint,
Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest( )
at System.Web.UI.Page.ProcessRequest(HttpContext context)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.
HttpApplication.IExecutionStep.Execute( )
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&
completedSynchronously)"
TargetSite: {System.Reflection.RuntimeMethodInfo}

Rom 10:9 Porque, se com a tua boca confessares a Jesus como Senhor, e em teu coração creres que Deus o ressuscitou dentre os mortos, será salvo;
Rom 10:10
pois é com o coração que se crê para a justiça, e com a boca se faz confissão para a salvação.

Rom 10:11
Porque a Escritura diz: Ninguém que nele crê será confundido.

Referências:


José Carlos Macoratti