Existem algumas regras para o tratamento de exceções que você deve ter em mente. Mas primeiro, é preciso lembrar que as exceções fazem parte da interface exposta pelo código; documentá-los . Isso é especialmente importante quando a interface é pública, é claro, mas também é uma boa ideia em interfaces privadas.
As exceções devem ser tratadas apenas no ponto em que o código pode fazer algo sensato com elas. A pior opção de manuseio é não fazer nada a respeito, o que deve ser feito apenas quando essa for exatamente a opção correta. (Quando tenho uma situação desse tipo no meu código, incluo um comentário nesse sentido, para não me preocupar com o corpo vazio.)
A segunda pior opção é lançar uma exceção não relacionada sem o original anexado como causa. O problema aqui é que as informações da exceção original que permitiriam o diagnóstico do problema foram perdidas; você está criando algo com o qual ninguém pode fazer nada (exceto reclamar que "não funciona" e todos sabemos como odiamos esses relatórios de erros).
Muito melhor é registrar a exceção. Isso permite que alguém descubra qual é o problema e corrija-o, mas você só deve registrar a exceção no ponto em que ela seria perdida ou relatada por uma conexão externa. Isso não ocorre porque o registro com mais frequência é um grande problema, como tal, mas porque o registro excessivo significa que o log consome mais espaço sem conter mais informações. Depois de registrar a exceção, você pode relatar uma précis ao usuário / cliente com boa consciência (desde que inclua também o tempo de geração - ou outro identificador de correlação) nesse relatório para que a versão curta possa ser correspondida com os detalhes, se necessário).
A melhor opção é, é claro, lidar completamente com a exceção, lidando com a situação de erro na sua totalidade. Se você pode fazer isso, faça de qualquer maneira! Pode até significar que você pode evitar ter que registrar a exceção.
Uma maneira de lidar com uma exceção é lançar outra exceção que fornece uma descrição de nível superior do problema (por exemplo, “ failed to initialize
” em vez de “ index out of bounds
”). Esse é um bom padrão, desde que você não perca as informações sobre a causa da exceção; use a exceção detalhada para inicializar a cause
exceção de nível superior ou registre os detalhes (conforme discutido acima). O registro é mais apropriado quando você está prestes a cruzar um limite entre processos, como uma chamada IPC, porque não há garantia de que a classe de exceção de baixo nível esteja presente no outro extremo da conexão. Manter como causa anexa é mais apropriado ao cruzar um limite interno.
Outro padrão que você vê é pegar e soltar:
try {
// ...
} catch (FooException e) {
throw e;
}
Esse é um anti-padrão, a menos que você tenha restrições de tipo de outras catch
cláusulas, o que significa que você não pode simplesmente deixar a exceção passar por conta própria. Então é apenas um recurso feio do Java.
Não há diferença real entre exceções verificadas e desmarcadas, exceto o fato de que você deve declarar exceções verificadas que cruzam os limites do método. Ainda é uma boa idéia documentar exceções não verificadas (com o @throws
comentário do javadoc) se você souber que elas estão sendo lançadas deliberadamente pelo seu código. Não jogue deliberadamente java.lang.Error
ou suas subclasses (a menos que esteja escrevendo uma implementação da JVM).
Opinião: um caso de erro inesperado sempre representa um erro no seu código. As exceções verificadas são uma maneira de gerenciar essa ameaça, e onde os desenvolvedores usam deliberadamente exceções não verificadas como uma maneira de evitar problemas ao lidar com casos de erro, você está acumulando muitas dívidas técnicas que precisarão limpar por algum tempo se você quiser código robusto. A manipulação de erro superficial não é profissional (e observar a manipulação de erro é uma boa maneira de determinar quão bom é o programador).