Buscar

Tratamento de exceções - parte 2

nome

João Marcos Sakalauska

Colunista ainda sem descrição. Caro colunista, por favor envie-nos sua descrição.

Olá amigos leitores!

Nesse artigo vou falar mais um pouco sobre: "Tratamento de Exceções". Caso você não tenha lido o artigo anterior peço que não continue esse artigo a menos que esteja bem inteirado sobre Tratamento de Exceções. Se preferir,
Clique aqui para ver o artigo anterior.
Como, no artigo anterior vimos as cláusulas Try, Except e Finally, nesse artigo veremos exemplos de Try, Except e Finally aninhados e também apresentaremos um meio de gerar exceções através do Raise.

Download do Aplicativo de Teste. (Fonte dos exemplos mostrados aqui no artigo)

Para iniciar, vamos relembrar como tratar exceções com as cláusulas Try, Except e Finally num determinado trecho do código.

Nunca construir tratamento de exceções dessa forma:

Try
  ...
Except
  ...
Finally
  ...
End;

Forma correta de tratar exceções usando Try, Except, Finally:

Try
  Try
    ...
  Except
    ...
  End;
Finally
  ...
End;

Podemos opcionalmente construir:

Try
  Try
    ...
  Except
    ...
  End;
Finally
  Try
    ...
  Except
    ...
  End;
  ...
End;

A seguir, apresento a lista das exceções que descrevem os tipos básicos - há centenas de classes da exceção:

Classe - Descrição

Exception - Exceção genérica, usada apenas como ancestral de todas as outras exceções
EAbort - Exceção silenciosa, pode ser gerada pelo procedimento Abort e não mostra nenhuma mensagem
EAccessViolation - Acesso inválido à memória, geralmente ocorre com objetos não inicializados
EConvertError - Erro de conversão de tipos
EDivByZero - Divisão de inteiro por zero
EInOutError - Erro de Entrada ou Saída reportado pelo sistema operacional
EIntOverFlow - Resultado de um cálculo inteiro excedeu o limite
EInvalidCast - TypeCast inválido com o operador as
EInvalidOp - Operação inválida com número de ponto flutuante
EOutOfMemory - Memória insuficiente
EOverflow - Resultado de um cálculo com número real excedeu o limite
ERangeError - Valor excede o limite do tipo inteiro ao qual foi atribuída
EUnderflow - Resultado de um cálculo com número real é menor que a faixa válida
EVariantError - Erro em operação com variant
EZeroDivide - Divisão de real por zero
EDatabaseError - Erro genérico de banco de dados, geralmente não é usado diretamente
EDBEngineError - Erro da BDE, descende de EDatabaseError e traz dados que podem identificar o erro

Exemplos:

1 - Nesse Exemplo, temos uma ocorrência normal da Aplicação utilizando Try, Finally -> Try, Except . O código na cláusula Try é executado por completo e em seguida, o código da cláusula Finally é executado entrando primeiro na cláusula Try que está dentro de Finally, como não é gerada nenhuma exceção dentro desse Try o código é executado por completo indo em seguida para a última linha do Finally.



2 - Nesse Exemplo, temos uma ocorrência normal da Aplicação utilizando Try -> Try, Except, Finally -> Try, Except. O código na cláusula Try -> Try é executado por completo e em seguida, o código da cláusula Finally é executado entrando primeiro na cláusula Try que está dentro de Finally, como não é gerada nenhuma exceção dentro desse Try o código é executado por completo indo em seguida para a última linha do Finally.



3 - Nesse Exemplo temos uma ocorrência de uma divisão por zero na Aplicação utilizando Try -> Try, Except, Finally -> Try, Except. O código na cláusula Try -> Try é executado até a linha "resultado := dividendo div divisor;", como nessa linha ocorre a exceção "EDivByZero" o código da cláusula Except é executado verificando o tipo de exceção que foi gerado, repare que nesse exemplo o Except possui apenas 3 tentativas (on EDivByZero do, on EAccessViolation do e else), a tentativa válida que será executada é on EDivByZero do e após isso o finally é chamado executando o código da mesma forma como mostramos nos exemplos anteriores.



4 - Nesse Exemplo, temos a ocorrência de um objeto que não criado, ou instancializado se preferir, ser utilizado para atribuição de valor em Try -> Try, Except, Finally -> Try, Except. O código na cláusula Try -> Try é executado até a linha "MinhaStringList.Text := '1';", como o objeto MinhaStringList não foi criado ("MinhaStringList := TStringList.Create;"), essa linha gera a exceção "EAccessViolation", então, o código da clásula Except é executado verificando o tipo de exceção que foi gerado, executando a linha on EAccessViolation do e após isso o finally é chamado executando o código da cláusula Try que por sua vez também gera uma exceção. A exceção ocorre porque tentamos destruir um objeto que não foi Criado, linha "MinhaStringList.Destroy;". Assim o código em Except é executado e após isso o restante do código do finally é executado.



5 - Nesse Exemplo, temos uma ocorrência parcialmente normal da Aplicação utilizando Try -> Try, Except, Finally -> Try, Except. O código na cláusula Try -> Try é executado por completo e em seguida, o código da clásula Finally é executado entrando primeiro na clásula Try que está dentro de Finally, quando a linha "MinhaStringList.Destroy;" é executada ocorre uma exceção porque tentamos destruir um objeto que já havia sido destruído, linha "MinhaStringList.Destroy;" em Try -> Try. Assim o código em Except é executado e após isso o restante do código do finally é executado.



6 - Nesse Exemplo, temos uma ocorrência parcialmente normal da Aplicação utilizando Try, Finally -> Try, Except. O código na cláusula Try é executado por completo e em seguida, o código da clásula Finally é executado entrando primeiro na clásula Try que está dentro de Finally, quando a linha "MinhaStringList.Destroy;" é executada ocorre uma exceção porque tentamos destruir um objeto que já havia sido destruído, linha "MinhaStringList.Destroy;" em Try. Além disso estamos forçando a finalização da Aplicação "Application.Terminate;". Assim o código em Except é executado e o Raise permite que a Exceção seja exibida ao usuário, então, a Aplicação nem chega a executar restante do código do em finally.
Creio que o Raise pode ser usado de outras formas também, esse é apenas um exemplo.



7 - Nesse Exemplo, temos uma ocorrência de uma divisão por zero na Aplicação utilizando Try -> Try, Except, Finally. O código na cláusula Try -> Try é executado até a linha "resultado := dividendo div divisor;", como nessa linha ocorre a exceção "EDivByZero" o código da clásula Except é executado, mas dessa vez, sem verificar o tipo de exceção que foi gerado, porque diferente do exemplo Número 3 que possuia 3 tentativas (on EDivByZero do, on EAccessViolation do e else), o exemplo 7 mostra um tratamento genérico, linha ("on E : Exception do"). Dessa forma a Aplicação entende que qualquer exceção ocorrida deve ser tratada pelo código dentro de "on E : Exception do". Essa idéia pode ser aplicada a outros tipos de Exceções, bastando apenas, você definir um tratamento genérico a todos os problemas que possam ocorrer.



Existem muitas formas de trabalhar com Tratamento de Exceções de forma com que a aplicação fique mais robusta. Um outro exemplo é a possibilidade de criarmos nossa própria exceção.

Em type digite:

type

   EUsuarioInvalido = class (Exception);


No evento OnClick do botão digite:


raise
EUsuarioInvalido.Create('Usuário Inválido');



Em execução:


Exceções e o Debbuger

Enquanto você estiver usando o Delphi para testar sua aplicação, verá que antes das mensagens de tratamento de exceções serem exibidas uma notificação de Exceção da IDE é exibida para você (passando a impressão de que o tratamento de exceção não funcionou), então, pressionando a tecla F9 é possível dar continuidade a aplicação. Mas as vezes isso fica sendo chato para testar nossa aplicação. No meu caso acabei testando fora do Delphi rodando o executável.
Para testar a aplicação sem que apareça a notifcação de Exceção da IDE do Delphi faça o seguinte:
(Delphi 2006) -> Desmarque a opção “Notify on language exceptions ”, no menu Tools | Options | Debugger Options | Borland Debuggers | Language Exceptions . Dessa forma as mensagens de exceção do depurador não serão mostradas.

Beleza galera, no próximo artigo irei passar mais alguns exemplos e apresentar outros tipos de exceções. Espero que isso possa ajudar, também espero que vocês possam contribuir com comentários referentes a experiências obtidas com o uso do tratamento de exceções. Dúvidas escrevam para João Marcos - jsakalauska@gmail.com.







Publicidade

Vote no artigo




Quantidade de votos: 0 votos
Aceitação: 0%


Detalhes do artigo

Categoria: Object pascal
Adicionado dia: 11/01/07
Por: João Marcos Sakalauska
Visualizado: 97055 vezes

Planeta Delphi - Tudo sobre programação Delphi Planeta Delphi - www.planetadelphi.com.br - Todos os direitos reservados | Copyright 2001-2009