Tratamento de Erro com Elegância
Veja neste artigo como tratar erro no delphi de uma maneira elegante.
Em seu livro Código Limpo Robert C. Martin, dedica um capitulo só para aborda sobre tratamento de erro, trabalhar com entradas de dados que podem estar errado, dispositivos podem falhar. Podemos afirmar que se uma coisa pode dar errado, ela vai dar errado e quando ocorre, nós como programadores somos responsável por certificar que nosso código faça o seja preciso fazer com eficiência e eficácia.
O tratamento de erro é um recurso muito importante, tanto para o usuário como para nós desenvolvedores. Mas não basta só tratar o erro, temos que tratar o erro com elegância e estilo.
Normalmente temos o costume de criar flags de erro ou retornar código para que o chamador possa verificar, como o código abaixo ilustra.
O problema desta abordagem que nossa função "logar" que acumula responsabilidade e não deixa o chamador tomar uma decisão sobre o erro lançado para o usuário, refactorando para uma bordagem "código limpo" podemos fazer da seguinte maneira:
Bem, como podemos observar o código fica mais claro, isso porque as duas preocupações que estavam no primeiro código, o algoritmo "validar usuário" e do tratamento de erro agora estão separadas.
O controle de Exceção podem definir o escopo dentro de um programa, ao executar o código na parte try da estruda try ...except...Finally assim você pode controlar como se fosse uma transação. Mas lembra-se que uma boa prática e deixar dentro da estrutura try... except... finally antes de lançar uma exceção.
Sempre forneça exceção com um contexto para que possa facilmente o localizar no seu fonte. Um erro ou atá mesmo pegar a stack trace de qualquer exceção. Crie mensagem de erro informativas e passe juntamente com as exceções e sempre que possível mencione a operação que falhou e o tipo da falha.
Define as classes de exceções segundo as necessidades do chamador, ao invez de usar exceções genéricas. Um exemplo de uma classificação ruim de exceção: aqui há uma estrutura de try... except... finally para uma chamada a um componente de terceiro, ela cobre todas as exceções que a chamada talvez lance
A estrutura acima possui muitas duplicações, e na maioria dos casos de tratamento de exceções fazemos assim: tratando exceções por exceções de chamadas de componentes de terceiros, uma boa prática é encapsular a chamada e garantir que retorne um tipo comum de exceções.
Nossa WRBoleto é um simples wrapper que captura e traduz as exceções lançadas pela :
Dessa maneira de empacotar componentes de terceiros, minimiza as dependências delas, você pode escolher migrar para um outro componente diferente no futuro sem muitos problemas.
E para finalizar, no livro Codigo Limpo Robert, dá duas dicas muito importantes que podem levar erros "Não retorne Null " e "Não passe Null", que deixa para você leitor, dá uma espiada nessas dicas importantes.
O tratamento de erro é um recurso muito importante, tanto para o usuário como para nós desenvolvedores. Mas não basta só tratar o erro, temos que tratar o erro com elegância e estilo.
Normalmente temos o costume de criar flags de erro ou retornar código para que o chamador possa verificar, como o código abaixo ilustra.
procedure Logar
begin
if (FUsuario.Login <> Emptystr) then
begin
ValidaUsuario(FUsuario);
if (FUsuario.Ativo) then
begin
GravaSessionUsuario(FUsuario);
CarregaConfiguracao(FUsuario);
end
else
begin
Showmensagem(" Usuario nao esta Ativo)
end
end
else
Showmensagem(" Login em branco ")
end.
O problema desta abordagem que nossa função "logar" que acumula responsabilidade e não deixa o chamador tomar uma decisão sobre o erro lançado para o usuário, refactorando para uma bordagem "código limpo" podemos fazer da seguinte maneira:
procedure logar;
begin
Try
doLogar
except on E: EControlUsuario do
ShowMessage(E.Message);
end;
end;
procedure doLocar;
begin
ValidaUsuario(FUsuario);
GravaSessionUsuario(FUsuario);
CarregaConfiguracao(FUsuario);
end;
Bem, como podemos observar o código fica mais claro, isso porque as duas preocupações que estavam no primeiro código, o algoritmo "validar usuário" e do tratamento de erro agora estão separadas.
O controle de Exceção podem definir o escopo dentro de um programa, ao executar o código na parte try da estruda try ...except...Finally assim você pode controlar como se fosse uma transação. Mas lembra-se que uma boa prática e deixar dentro da estrutura try... except... finally antes de lançar uma exceção.
Sempre forneça exceção com um contexto para que possa facilmente o localizar no seu fonte. Um erro ou atá mesmo pegar a stack trace de qualquer exceção. Crie mensagem de erro informativas e passe juntamente com as exceções e sempre que possível mencione a operação que falhou e o tipo da falha.
Define as classes de exceções segundo as necessidades do chamador, ao invez de usar exceções genéricas. Um exemplo de uma classificação ruim de exceção: aqui há uma estrutura de try... except... finally para uma chamada a um componente de terceiro, ela cobre todas as exceções que a chamada talvez lance
ABoleto:= TBoleto.create(ADados);
try
ABoleto.Gerar;
except
on EConversionError
logar(E.Message)
ShowMessage(E.ClassName+'' Nao e possivel converter valores: ''+E.Message);
on EZeroDivide
logar(E.Message)
ShowMessage(E.ClassName+'': Verifique os tryvalores ''+E.Message);
...
finally
....
end;
A estrutura acima possui muitas duplicações, e na maioria dos casos de tratamento de exceções fazemos assim: tratando exceções por exceções de chamadas de componentes de terceiros, uma boa prática é encapsular a chamada e garantir que retorne um tipo comum de exceções.
try
ABoleto := WRBoleto.create(ADados);
try{
Aboleto.gerar;
except
logar(E.Message)
ShowMessage(E.Message);
end
finally
....
end;
Nossa WRBoleto é um simples wrapper que captura e traduz as exceções lançadas pela :
type
EWRBoleto : Exception;
WRBoleto = class
FBoleto :TBoleto
....
procedure Gerar;
...
......
procedure WRBoleto.Gerar;
begin
FBoleto.Gerar;
except
on EConversionError
raise EWRBoleto.Create(E.Message);
on EZeroDivide
raise EWRBoleto.Create(E.Message);
end;
Dessa maneira de empacotar componentes de terceiros, minimiza as dependências delas, você pode escolher migrar para um outro componente diferente no futuro sem muitos problemas.
E para finalizar, no livro Codigo Limpo Robert, dá duas dicas muito importantes que podem levar erros "Não retorne Null " e "Não passe Null", que deixa para você leitor, dá uma espiada nessas dicas importantes.
Marcelo Fernandes
Sou analista,programador e arquiteto na Questor Sistema. Trabalha com Delphi, desde da versao 5, e Firebird,Mysql desenvolvendo aplicações cliente-servidor. Formado em Tecnologia de Processamento de dados pela Cesumar, na cidade de Maringá-Pr.
O que você achou deste post?
Cursos relacionados
Publicidade



