Desenvolvimento - Visual Basic .NET

Depurando e Tratando Erros no VB.NET

Quando desenvolvemos Sistemas, sejam eles de pequeno, médio ou grande porte, temos que atentarmos aos erros que podem ocorrer.

por Israel Aéce



Quando desenvolvemos Sistemas, sejam eles de pequeno, médio ou grande porte, temos que atentarmos aos erros que podem ocorrer.

Quanto maior e mais complexo o Sistema, mais ele tende à dar erro e por isso temos sempre que adotar a Depuração e Tratamento de Erros para que a Solução fique o mais perto do "perfeito" possível.

Então o que é Depurar e Tratar Erros? Explico:

Depurar: Por mais que tentamos criar um código perfeito e isento à erros, eles sempre acabam acontecendo. A idéia é identificar as áreas mais frágeis do código e adotar boas práticas de programação para tornar os erros mais evidentes possíveis.

Tratamento de Erro: Mesmo que isento de erros, o código ainda poderá falhar durante o tempo de execução. Além disso temos que prever os erros que podem nascer no ambiente do Sistema, tal como: um serviço que você está tentando acessar e o mesmo está indisponível.

Depurando

Erros de Sintaxe: Esse é tipo mais comum quando desenvolvemos um Sistema. Ele ocorre quando há alguma sintaxe inválida em seu código e provavelmente esse será o primeiro erro que você irá identificar, pois são fáceis de serem localizados e solucionados.

Um Exemplo seria não fechar uma instrução If:

If ... Then
...
ElseIf ... Then
...
If ... Then
...
End If

Erros Lógicos: Esses erros acontecem quando há algum erro na lógica de programação, e ao contrário dos Erros de Sintaxe, esse tipos de erros são mais difíceis de serem localizados e resolvidos. Abaixo mostrei os erros mais comuns:

  • Incompatibilidade de Tipo: Ocorre quando tentamos trabalhar com tipos de dados incompatíveis. Um exemplo seria atribuir à uma variável do tipo Interger ou Date uma String.

  • Divisão por Zero: Apesar de um erro muito comum, acredito que todo programador sabe que não é possível dividir um número por Zero, mas na maioria das vezes o que provoca esse erro é quando o divisor é uma variável e em que algum momento do código ela ficou com o valor Zero, o que provocará o erro.

  • Objeto Inexistente: Ocorre quando tentamos utilizar um objeto que falhou ou não foi criado.

  • Dados Inválidos: Este tipo de erro ocorre quando o Sistema está aceitando dados inválidos, como por exemplo em um Sistema de Locadora de Vídeo aceitar a data de 29 de Feveireiro para a devolução de um DVD/VHS, com isso você pode levar até 4 anos para devolvê-lo.

  • Saída Incorreta: Ocorre quando usamos uma Função que retorna um valor diferente do qual estamos esperando.

Erros de Sistema: Esses erros podem acontecer pela execução de um código falho em seu Sistema ou até mesmo na CLR. Outros erros que poderiam se enquadrar aqui seriam:

  • A falha no acesso de um componente;
  • Um servidor inexistente;
  • Um serviço está indisponível.

Apesar de estarmos longe de abordarmos todos os erros que possam vir à acontecer, está pequena lista já lhe auxiliará à procurar por erros em seu Sistema.

Alguns bons hábitos para deixar seu código legível e para localizar facilmente possíveis erros:

  • Identar o Código;
  • Usar convenção de nomes que façam sentido;
  • Escrever o máximo de comentário possível;
  • Estruturar o Código;
  • Ativar o Option Explicit.

Testando Condições de Erro

Depois de pronto, chega a parte mais interessante e divertida, ou seja, testá-lo para ver se realmente funciona como desejamos. Faça isso em duas etapas:

1 - Primeiramente seja "Amigo" do Sistema não digitando valores que não façam sentido como uma letra em um campo de Idade.

2 - Em segundo lugar esqueça o bom senso e abuse dos mais mirabolantes erros que possa acontecer para ver se realmente eles estã sendo tratados corretamente.

Além dessas técnicas, se você utiliza o Visual Studio .NET ele fornece diversas ferramentas para auxiliar os desenvolvedores. Aqui mesmo no site Linha de Código existe um artigo muito bom escrito pelo José Carlos Macoratti: http://www.linhadecodigo.com.br/artigos.asp?id_ac=166&pag=1.

Tratando Erros

Depois de tudo o que vimos anteriormente, não pensem que está tudo funcionando perfeitamente.

Ainda nos resta tratar os erros que podem acontecer em tempo de execução, pois não conseguiremos saber se eles vão ou não ocorrer.

É justamente para isso que existem os Tratamentos de Erros, para que possamos captar os erros e tratá-los em tempo de execução.

OBS.: Abordaremos daqui em diante o Tratamento de Erros Estruturado (Try...Catch...Finally), pois apesar de ainda existir o "On Error Resume Next" e o "On Error Go To" no VB.NET, não falaremos sobre a forma não Estruturada, mesmo porque ela está aí apenas para manter compatibilidade com projetos desenvolvidos em Visual Basic 6.

Como funciona Tratamento de Erros Estruturado:

1 - Executamos uma mais linhas de código que podem ou não gerar erros.

2 - Se acontecer algum erro, o manipulador do mesmo será acionado caso exista.

3 - Você também pode definir um manipulador Genérico para tratar qualquer tipo de erro.

Exceções (Exceptions)

Uma exceção é uma condição de erro ou comportamento inesperado que ocorre durante a execução de um programa e, conseqüentemente, corrompe o fluxo normal das instruções.

A Plataforma .NET disponibiliza uma Classe chamada System.Exception, que é a classe base para todas as exceções.

Essa classe contém propriedades que informam sobre a exceção:

  • HelpLink: Esta propriedade com uma URL apontando para um arquivo contendo informações de ajuda sobre a exceção que ocorreu.

  • InnerInformation: Referencia uma exceção interna. Se uma outra exceção for capturada e passada para um outro Handler de exceção, isso retorna a referência à primeira exceção.

  • Message: Propriedade de contém a mensagem de erro da Exception.

  • Source: Retorna informações do Sistema que gerou o erro.

  • StackTrace: Esta propriedade contém o rastreamento de pilha. Ela pode ser usada para determinar a localização da ocorrência do erro.

  • TargetSite: Informações sobre o método que lança a exceção.

Além das propriedades acima também temos o método ToString() da classe Exception que envia ao cliente informações como mensagem de erro, nome da exceção e pilha de rastreamento.

Utilizando o Try...Catch...Finally

Mostrarei agora como funciona o Tratamento de Erros Estruturado (Try...Catch...Finally)

Veja o exemplo:

Try
"Código que deve ser gerenciado.
"Pois pode ocorrer algum erro.
Catch
"Manipular de erro que poderia acontecer no bloco Try.
Finally
"Código de Limpeza.
End Try

O bloco de código que será inserido dentro de Try será "vigiado", pois sabemos que ali se encontra um trecho de código que pode ou não ocasionar um erro. Se ocorreu um erro, o bloco Catch é executado. Dentro do bloco Catch conterá manipuladores para as diferentes exceções que podem ocorrer dentro do bloco Try. Se nenhum manipulador específico para a exceção for encontrado, o VB.NET executa um manipulador de erro genérico. E se esse manipulador genérico também não for encontrado o usuário final visualizará o erro.

Ilustrarei abaixo o processo do Try...Catch...Finally:


Bloco Try

Ainda no bloco Try podemos utilizar blocos Try...Catch aninhados, ou seja, se a exceção não for manipulada por pelo bloco aninhado ela é entregue ao bloco Try externo, em que ela terá mais uma chance de ser tratada.

Podemos também utilizar o Exit Try para sairmos do bloco Try.

Bloco Catch

Podemos utilizar a técnica de aninhamento no bloco Catch também, ou seja, você pode ter por exemplo cinco manipuladores de exceções, uma para cada exceção específica.

Temos também Throw que serve para você lançar suas próprias exceções ou até mesmo lançar a exceção ocorrida para que ela seja tratada. Veremos mais abaixo um exemplo de como utilizá-lo.

OBS.: Devemos sempre escrever os manipuladores de exceções do mais específico ao mais genérico, pois se fizermos ao contrário, ele sempre manipulará o erro com o manipulador genérico de exceção.

Bloco Finally

O bloco Finally contém código de limpeza/encerramento, como por exemplo, fechar conexões com Banco de Dados, liberar objetos, etc. Lembrando que o bloco Finally é executado independentemente se houve ou não uma exceção.

Para finalizar sobre o Try...Catch...Finally devemos levar em consideração que se tratam de blocos de código, logo se declararmos uma variável dentro do bloco Try ela será vista apenas dentro ele, os blocos Catch e Finally não poderão manipular tais variáveis, acusando que a mesma não foi declarada. Para contornar isso, declare as variáveis que deseja utilizar antes do bloco Try...Catch...Finally.

Abaixo um exemplo de como utilizar o Try...Catch...Finally:

Public Sub ConectandoDB()
Dim sqlconn As SqlConnection = New SqlConnection("StringConn")
Try
sqlconn.Open()
Catch ex As Exception
MessageBox.Show("Ocorreu um erro: " & ex.ToString)
Finally
If sqlconn.State = ConnectionState.Open Then
sqlconn.Close()
End If
End Try
End Sub

Utilizando o Throw para disparar as exceções.

Public Sub ConectandoDB()
Dim sqlconn As SqlConnection = New SqlConnection("StringConn")
Try
sqlconn.Open()
Catch ex As Exception
Throw ex
Finally
If sqlconn.State = ConnectionState.Open Then
sqlconn.Close()
End If
End Try
End Sub

Utilizando o Throw podemos tratar a exceção onde o método ConectandoDB() foi chamado. Isso é muito útil quando trabalhamos com Class Library.

Conclusão: Espero que ao ler esse artigo o leitor possa entender como funciona o Tratamento de Erros no VB.NET e o utilize para implementar em seu código quando necessário, e que também possam entender que a Depuração é uma etapa bastante importante que deve ser realizada em qualquer Sistema para garantirmos que ele será à prova de erros.
Israel Aéce

Israel Aéce - Especialista em tecnologias de desenvolvimento Microsoft, atua como desenvolvedor de aplicações para o mercado financeiro utilizando a plataforma .NET. Como instrutor Microsoft, leciona sobre o desenvolvimento de aplicações .NET. É palestrante em diversos eventos Microsoft no Brasil e autor de diversos artigos que podem ser lidos a partir de seu site http://www.israelaece.com/. Possui as seguintes credenciais: MVP (Connected System Developer), MCP, MCAD, MCTS (Web, Windows, Distributed, ASP.NET 3.5, ADO.NET 3.5, Windows Forms 3.5 e WCF), MCPD (Web, Windows, Enterprise, ASP.NET 3.5 e Windows 3.5) e MCT.