Compartilhar via


Uma exceção à regra, parte 1

 

Rob Howard
Microsoft Corporation

23 de julho de 2001

Vamos encarar, quando escrevemos aplicativos Web , ocasionalmente temos bugs (ou em nosso mundo mais politicamente correto, problemas) em nosso código. Infelizmente, sempre parece que quanto mais sênior o testador, ou seja, CEO, CIO, membros do conselho, VC e assim por diante, mais frequentes ou sérios esses problemas tendem a ser.

Se você tiver feito qualquer desenvolvimento no ASP, lembrará de mensagens de erro ASP maravilhosamente úteis semelhantes a:

HTTP 500.100 - Internal Server Error - ASP error
Error Type: Microsoft VBScript runtime (0x800A01A8)

Como desenvolvedor, sua primeira reação ao ver essa mensagem de erro geralmente é: "hein?" Em seguida, você converte o erro : um erro de servidor interno HTTP 500 indicando que há um problema com o código ASP. A próxima parte é o tipo de erro, nesse caso, é o código HRESULT de 0x800A01AB, que, se você tiver tempo suficiente em suas mãos, poderá aplicar grep MSDN (ou usar seu anel de decodificador de segredo COM HRESULT do Captain Crunch) e descobrir que o código tentou fazer uma chamada de associação tardia em um método que não existia.

Infelizmente para nós, é muito mais comum que nossos testadores seniores descubram esses problemas. E, em vez de arquivar um bug, esses testadores seniores geralmente seguem uma rota menos construtiva como pegar o telefone e gritar com alguém, geralmente seu chefe. A pergunta comum é: "por que você está usando o Microsoft ASP se ele causa erros? Na verdade, ele diz isso ali mesmo 'erro asp'."

ASP.NET nos permite lidar facilmente com esses tipos de erros e outros problemas de runtime de maneira muito mais estruturada e amigável. Nosso aplicativo pode fornecer ao desenvolvedor uma mensagem de erro avançada e específica do desenvolvedor e nossos testadores seniores com mensagens lindas e ricamente obscuras que os deixam encantados com a complexidade de seu sistema.

Além disso, você nunca verá uma página de erro ASP.NET (a menos que você mesmo escreva) que diga ASP.NET error. Queremos mantê-lo honesto, então dizemos Application error.

tratamento de exceções ASP.NET

ASP.NET nos permite criar aplicativos Web com qualquer linguagem seguindo a CLS (Common Language Specification). As linguagens que seguem o CLS, uma especificação enviada ao ECMA para padronização, são capazes de serem executadas no CLR (Common Language Runtime). O CLR fornece recursos como coleta de lixo, execução segura de código e tratamento de exceções estruturadas e muito mais.

Podemos aproveitar esse tratamento de exceção estruturado e independente de linguagem em nossos aplicativos ASP.NET. O tratamento de exceções estruturadas é feito por meio de blocos try/catch/finally e nos força a lidar com exceções quando elas ocorrem. Se uma exceção for gerada e não tratarmos explicitamente a exceção, ocorrerá uma exceção geral ASP.NET, forçando o aplicativo a terminar sem permitir que o código continue em execução, resultando em uma página de erro. Isso torna a localização de erros muito, muito mais fácil.

Isso é muito diferente do código ASP. Com o código ASP, podemos chamar o método de um objeto COM do Visual Basic 6 e, se ocorrer um erro dentro do método , um código de erro (um HRESULT) será retornado. No entanto, é nossa responsabilidade marcar pelo erro, geralmente encapsulando nosso código da seguinte maneira (pseudocódigo):

<%
On Error Resume Next
...
dataObject.SomeBadMethod()
If Error.Number <> 0 Then
  Response.Write("An error occurred in the call to SomeBadMethod()")
  Response.End
End If
dataObject.SomeGoodMethod()
%>

Se não marcar para Error.Number no pseudocódigo ASP acima, nosso código continuará em execução depois de chamar SomeBadMethod() e chamar diretamente em SomeGoodMethod().

O conceito de verificação de erros ainda existe no ASP.NET, mas devemos lidar com o erro quando ele ocorrer:

<Script runat=server>
Public Sub Page_Load(sender As Object, e As EventArgs)
  ...
  Begin Try
    dataObject.SomeBadMethod()
  Catch
    ' Looks like an exception occurred, do work to either
    ' handle the error and clear the exception or fail
  End Try
  ...
End Sub
</Script>

A principal diferença é que agora lidamos com as exceções usando Try/Catch/Finally exclusivamente. Essa é uma boa notícia. Quando ocorre um erro, obtemos uma instância de exceção ou possivelmente uma instância derivada e mais especializada, como uma NoNullAllowedException ao tentar inserir um valor nulo em uma linha de tabela SQL que não permite valor nulo.

As exceções nos fornecem informações detalhadas sobre o que ocorreu; por exemplo, rastreamento de pilha, detalhes da exceção interna, mensagem e detalhes adicionais. Isso é muito melhor do que um código de erro COM HRESULT!

Exceções sem tratamento

Anteriormente, mencionamos que ASP.NET, ou melhor, o CLR, nos força a lidar com uma exceção quando ocorre um erro. Obviamente, não escrevemos blocos Try/Catch/Finally em todo o nosso código e, nos casos em que não escrevemos, ASP.NET ainda nos fornece algumas instalações para lidar com a exceção por meio de dois eventos:

  • Page_Error
  • Application_Error

Manipuladores de eventos de erro de página e aplicativo

O caso existe quando uma exceção é inesperada e não ocorre dentro dos limites de um bloco Try/Catch/Finally. Essas exceções geralmente são um indicador de que algo está substancialmente errado com o aplicativo. Ou seja, ocorreu algum erro anormal e não há uma maneira normal de sair do erro. Nessas situações, em que não encapsulamos o código com falha com um bloco Try/Catch/Finally, ainda temos a opção de lidar com o erro no nível da Página ou do Aplicativo.

Se optarmos por lidar com o erro no nível da página, devemos fornecer uma implementação para o Page_Error evento:

VB.NET

Public Sub Page_Error(sender As Object, e As EventArgs)
   ' Implementation here
End Sub

C#

public void Page_Error(Object sender, EventArgs e) {
   // Implementation here
}

Esse evento é implementado na Página na qual o erro pode ocorrer.

Como alternativa, também podemos implementar o Application_Error evento. Ao contrário do Page_Error evento, o Application_Error evento é implementado em global.asax e qualquer exceção sem tratamento que ocorre em nosso aplicativo gera esse evento (se implementado):

VB.NET

Public Sub Application_Error(sender As Object, e As EventArgs)
   ' Implementation here
End Sub

C#

public void Application_Error(Object sender, EventArgs e) {
   // Implementation here
}

Dentro de qualquer um desses eventos, podemos executar código, como enviar um email para o administrador ou gravar no log de eventos, observando que ocorreu um erro. Na próxima coluna, discutiremos a gravação no Log de Eventos do Windows.

Além de executar o código para alertar as pessoas necessárias para a exceção em nosso aplicativo, ainda temos a oportunidade de massagear a exceção, limpando-a, se necessário. Temos acesso à exceção que ocorreu por meio do método Server.GetLastError() que retorna uma classe Exception e podemos limpar a exceção usando a API Server.ClearError().

Resumo

Graças ao Common Language Runtime, ASP.NET desenvolvedores agora podem escrever código de tratamento de erro estruturado usando blocos Try/Catch/Finally. O CLR nos força a lidar com o erro quando o erro ocorre, ao contrário de ASP/COM, em que o erro pode ir desmarcado e potencialmente causar confusão mais tarde. Na próxima coluna, continuaremos nossa discussão sobre ASP.NET tratamento de erros e examinaremos a página de erro personalizada que ASP.NET gera. Também discutiremos como podemos implementar o código que pode gravar nossos detalhes de exceção no Log de Eventos do Windows.

Atualização da comunidade

Grupos de Usuários: Recentemente falei em um grande grupo de usuários do .NET em St. Louis. Em 9de agosto, estarei em Dallas falando no grupo de outro usuário. Para obter mais informações, confira http://www.dnug.net/ViewGroup.aspx?id=21. Em seguida, no dia28 de agosto, falarei em um grupo de usuários em San Diego (postarei uma URL mais tarde). Se você ainda não ingressou em um grupo de usuários do .NET e está falando sério sobre como aprender o .NET, eu definitivamente recomendo isso.

Conferências: A conferência Conexões do Microsoft ASP.NET, de18 a21 de setembro em Orlando, FL, será uma grande conferência totalmente focada em ASP.NET. Para obter mais informações, confira http://www.asp-connections.com.

revista ASP.NET: Nos últimos seis meses, a equipe de ASP.NET tem trabalhado em estreita colaboração com o Grupo de Comunicações de Informantes para montar uma revista dedicada a desenvolvedores ASP.NET. A revista será chamada de asp.netPRO e estará disponível ainda neste outono. A equipe ASP.NET vai participar fortemente da revista. Teremos uma coluna Pergunte à equipe de ASP.NET e muitas outras contribuições da equipe ASP.NET, bem como muitos de nossos incrivelmente talentosos especialistas em ASP.NET de terceiros. Para obter mais detalhes, além de se inscrever para um problema gratuito, consulte http://www.aspnetpro.com.

 

Rob Howard é gerente do programa para ASP.NET na equipe de .NET Framework. Ele passa o tempo livre que tem com sua família ou pesca de moscas no leste de Washington.