Exceções de Banco embrulhadas em RuntimeException Genérica

Pessoal,

Recentemente fui exposto a prática de código obscena abaixo ilustrada:

[code]public class DAOException extends RuntimeException {

public DAOException(Throwable cause) {
    super(cause);
}

}[/code]

[code]public class XxxxYyyyDAOImpl implements XxxxDAO {

public Xxxx metodo1() {
    try {
        //....
        return null;
    } catch (Exception e) {
        throw new DAOException(e);
    }
}

public List<Xxxx> metodo2() {
    try {
        //....
        return null;
    } catch (Exception e) {
        throw new DAOException(e);
    }
}

//...

}
[/code]
O resultado, como esperado, são trocentas exceções de Runtime genéricas no log e ausência quase absoluta de código de tratamento de erros no projeto.
Ao indagar com “a fonte” fui informado de que ele aprendeu assim na Caelum. Como conheço o nível acadêmico e técnico altíssimo da escola, tenho certeza absoluta de que esse “padrão” não foi recomendado pelos instrutores, pelo menos não fora de um contexto bem específico.
Sendo assim, vim perguntar em primeira mão, em que contexto esse código foi apresentado (se é que foi apresentado)? E, só para matar o caso de vez, o que vocês acham desse tipo de prática de codificação?

rsrs eu ri =]

mas quanto ao codigo…
Cara, tratamento de erro fod@stico!
tipow… Deu erro? Vc que se fod@!
><"

Interessante essa discussão…

Até onde eu entendi o negócio, checked exceptions fazem parte do contrato. Exemplo: faz sentido eu lançar uma excessão UserNotFound no método login() de uma classe, e quem usa este método vai efetivamente usar essa informação e tomar uma decisão baseado nela.

Agora, o que eu faço com um SQLException além de mostrar na tela ou gravar em log?

Pessoalmente eu concordo com essa prática. Checked Exceptions para regras e RuntimeExceptions para excessões.

Recentemente limpei um código que tinha SQLExceptions em praticamente todo santo lugar, fazendo exatamente isso aí.

Realmente SQLExceptions são amplas, e recorrer a gerErrorCode tem lá seus problemas (não é impossível porém ter código que faça coisas diferentes para uma violação de constraint e um timeout por exemplo), eu consigo até entender que o tratamento de SQLExceptions possa ser simplesmente “jogue no log” em alguns contextos, e o porquê da discussão sobre transformá-las em exceções de runtime.
Eu particularmente sou a favor de fazer o tratamento em algum ponto, ou pelo menos embrulhar apenas SQLExceptions, diferenciando-as de outras exceções de runtime como NullPointerExceptions, mesmo em um contexto JDBC puro. Mas tenho que admitir que o Paulo já me abriu os olhos sobre como essa idéia de embrulhar exceções DAO surgiu.
No caso específico da base em questão porém, existe o Hibernate no meio com toda uma hierarquia bem definida de exceções (de runtime) http://docs.jboss.org/hibernate/stable/core/api/org/hibernate/HibernateException.html. Essa DAOException é um embrulho desnecessário que dificulta bastante o tratamento de erros, e quando misturada com técnicas como Open Session In View (que, diga-se de passagem, apesar de ter seus benefícios, também não é das minhas favoritas) gera exceções que são bem chatas de rastrear, o que é piorado ao infinito quando seu log só mostra os 3 primeiros níveis do stack trace em produção (lol). Quando eu vejo um aplicativo com milhares de exceções por dia disparadas para o Log sem tratamento prévio, todas difíceis de serem rastreadas e sem ninguém que tenha noção sobre quais exceções são preocupantes e quais caem na categoria “ORA-00000” minha tendência é ficar preocupado :D.

[quote=PauloBrito]
Agora, o que eu faço com um SQLException além de mostrar na tela ou gravar em log?

Pessoalmente eu concordo com essa prática. Checked Exceptions para regras e RuntimeExceptions para excessões.

Recentemente limpei um código que tinha SQLExceptions em praticamente todo santo lugar, fazendo exatamente isso aí. [/quote]

E isso é bom ou ruim? :wink:

Acho que você sabe de coisas que eu não sei sobre o primeiro post…

É bom. Considerando as 5 etapas da tristeza, eu já passei da raiva (Por que cargas d’agua alguém faz uma coisa dessas? :D), para negociação (ah, talvez existam casos justificáveis), depressão (droga, mas sou eu que tenho que dar manutenção nisso) e aceitação (então foi assim que começou, já foi feito, agora o problema é meu). Foi um resultado expressivo! hehehe :D.

É, desculpe o desabafo, sexta-feira brava hehehe.

Não tem nada de errado com essa prática. Na verdade, muitas APIs já fazem isso, como é o caso do Spring e o Hibernate.

SQLException é o tipo de exceção que não deveria estar ocorrendo. O java só a dispara como uma exception verificada, pois ele não faz o tratamento da conexão, do statement e do resultset, que deveria ser responsabilidade do DAO fazer. Se o DAO faz (e ele deveria), então, não tem porque repassar uma exception tão crítica que, a princípio, não tem mesmo como ser recuperada(o que você vai fazer se a base não responde?)

Para tratá-la, faça como você faria com qualquer RuntimeException inesperada, logue-a. E para isso nem precisa de catch, basta criar um DefaultUncaughtExceptionHandler (se for uma aplicação de desktop), ou configurar seu servidor web.

Agora, o problema é se os métodos do DAO, internamente, não estiverem fazendo o tratamento adequado da SQL exception (fechar conexões e statements). Aí você pode ter leaks e coisas chatas de resolver.