Aqui está um fato interessante: Não código está livre de erros - de fato, algum código está cheio de "erros" de propósito.
O que é um erro em um aplicativo? Um erro é uma solução codificada incorretamente para um problema. Tais são erros lógicos isso pode levar a resultados de funções incorretas, onde tudo parece bem organizado, mas o resultado do aplicativo é completamente inutilizável. Com erros de lógica, um inscrição pode ou não parar de funcionar.
As exceções podem incluir erros no seu código onde você tenta dividir números com zero ou tenta usar blocos de memória liberada ou tenta fornecer parâmetros incorretos para uma função. No entanto, uma exceção em um aplicativo nem sempre é um erro.
Exceções e a classe de exceção
Exceções são condições especiais que requerem tratamento especial. Quando ocorre uma condição do tipo erro, o programa gera uma exceção.
Você (como criador do aplicativo) manipulará exceções para tornar seu aplicativo mais suscetível a erros e responder à condição excepcional.
Na maioria dos casos, você será o escritor do aplicativo e também o escritor da biblioteca. Portanto, você precisa saber como gerar exceções (da sua biblioteca) e como lidar com elas (do seu aplicativo).
O artigo sobre manipulação de erros e exceções fornece algumas diretrizes básicas sobre como se proteger contra erros usando os blocos protegidos try / except / end e try / finalmente / end para responder ou lidar com condições excepcionais.
Uma simples tentativa / exceto blocos de proteção é semelhante a:
tentar
ThisFunctionMightRaiseAnException ();
exceto// manipula todas as exceções levantadas em ThisFunctionMightRaiseAnException () aqui
fim;
A ThisFunctionMightRaiseAnException pode ter, em sua implementação, uma linha de código como
levantar Exceção. Create ('condição especial!');
A exceção é uma classe especial (uma das poucas sem um T na frente do nome) definida na unidade sysutils.pas. A unidade SysUtils define vários descendentes de exceção de finalidade especial (e, portanto, cria uma hierarquia de classes de exceção) como ERangeError, EDivByZero, EIntOverflow, etc.
Na maioria dos casos, as exceções que você manipularia no bloco try / except protegido não seriam da exceção (base), mas de alguma classe descendente de exceção especial definida na VCL ou na biblioteca em que você está usando.
Manipulando exceções usando Try / Except
Para capturar e manipular um tipo de exceção, você deve criar um manipulador de exceção "no tipo de exceção". O "on exception do" se parece muito com a declaração de caso clássica:
tentar
ThisFunctionMightRaiseAnException;
exceto EZeroDivide dobegin// algo ao dividir por zerofim;
em EIntOverflow dobegin// algo quando cálculo inteiro muito grandefim;
elsebegin// algo quando outros tipos de exceção são geradosfim;
fim;
Observe que a parte else captaria todas as (outras) exceções, incluindo aquelas sobre as quais você não sabe nada. Em geral, seu código deve lidar apenas com exceções que você realmente sabe como lidar e espera que sejam lançadas.
Além disso, você nunca deve "comer" uma exceção:
tentar
ThisFunctionMightRaiseAnException;
exceto
fim;
Comer a exceção significa que você não sabe como lidar com a exceção ou não deseja que os usuários vejam a exceção ou qualquer outra coisa.
Quando você lida com a exceção e precisa de mais dados (afinal é uma instância de uma classe), apenas o tipo de exceção que você pode fazer:
tentar
ThisFunctionMightRaiseAnException;
exceto E: Exceção dobegin
ShowMessage (E.Message);
fim;
fim;
O "E" em "E: Exception" é uma variável de exceção temporária do tipo especificado após o caractere da coluna (no exemplo acima, a classe Exception base). Usando E, você pode ler (ou gravar) valores no objeto de exceção, como obter ou definir a propriedade Message.
Quem liberta a exceção?
Você já reparou como as exceções são realmente instâncias de uma classe descendente de Exception? A palavra-chave raise lança uma instância de classe de exceção. O que você cria (a instância de exceção é um objeto), você também precisa libertar. Se você (como escritor da biblioteca) criar uma instância, o usuário do aplicativo a liberará?
Aqui está o Delphi magia: manipular uma exceção destrói automaticamente o objeto de exceção. Isso significa que, quando você escreve o código no bloco "except / end", ele libera a memória de exceção.
Então, o que acontece se ThisFunctionMightRaiseAnException realmente gerar uma exceção e você não a estiver manipulando (isso não é o mesmo que "comê-la")?
E quando Número / 0 não é tratado?
Quando uma exceção não tratada é lançada em seu código, o Delphi novamente lida magicamente com a exceção, exibindo a caixa de diálogo de erro para o usuário. Na maioria dos casos, esse diálogo não fornecerá dados suficientes para o usuário (e, finalmente, você) entender a causa da exceção.
Isso é controlado pelo loop de mensagens de nível superior do Delphi, onde todos exceções estão sendo processadas pelo objeto Aplicativo global e seu método HandleException.
Para manipular exceções globalmente e mostrar sua própria caixa de diálogo mais amigável, você pode escrever o código para os TApplicationEvents. Manipulador de eventos OnException.
Observe que o objeto Aplicativo global é definido na unidade Formulários. O TApplicationEvents é um componente que você pode usar para interceptar os eventos do objeto Aplicativo global.