Tratar Exceção

Olá Pessoal Bom Dia!

Suponhamos que tenho um sistema dividido em 3 camadas básicas
controle, negócio, persistência… e que executo um comando na camada de persistência o qual me retorna uma exceção. A dúvida é, devo tratar o erro com catch na camada de persistência ou devo dar trows até chegar …?

Abraço, JOhn. :cool:

Eae…

Isso depende do erro. E onde fica mais conveniente tratar…

As vezes um erro, por exemplo, que dispare um NullPointerException tu pode tratar na camada de apresentação… disparando uma messagem na tela informando ao usuario que o que ele que não existe… Enfim…ou simplesmente tratar na camada de persistencia e ignorar o objeto NULL…

Acho que é isso… acredito ser uma questão de bom senso.

Abraços!

Olá Felipe, Obrigado por responder.

O problema que me deparo é o seguinte. Suponhamos que temos uma equipe de pessoas que desenvolva a camada de persistência para posteriormente iniciar a camada de negócio.

Na minha camada de persistência tenho um método que lista objetos, e digamos que as exceções aException, bException e cException possam acontecer nesse método… O que devo fazer? faço um try catch e apenas dou um e.printStackTrace() e retorno nulll? dou e.printStrackTrace() seguido de um trows? nesse caso não séria melhor eu apenas adicionar um throws ao método?

O problema se resume a: tenho que ficar tratando as mesmas exceções em todas as camadas da aplicação?

Grato, JOhn. :cool:

[quote=“JohnTortugo”]Olá Felipe, Obrigado por responder.

O problema que me deparo é o seguinte. Suponhamos que temos uma equipe de pessoas que desenvolva a camada de persistência para posteriormente iniciar a camada de negócio.

Na minha camada de persistência tenho um método que lista objetos, e digamos que as exceções aException, bException e cException possam acontecer nesse método… O que devo fazer? faço um try catch e apenas dou um e.printStackTrace() e retorno nulll?
[/quote]

NUNCA FAÇA ISSO. NUNCA JAMAIS!

[quote]
dou e.printStrackTrace() seguido de um trows? nesse caso não séria melhor eu apenas adicionar um throws ao método?

O problema se resume a: tenho que ficar tratando as mesmas exceções em todas as camadas da aplicação?

Grato, JOhn. :cool:[/quote]

Quando uma exceção ocorre vc deve saber se pode resolvê-la. Ou seja, se o programa pode driblar o problema. Se pode, simplesmente resolve e pronto. Sem log, sem throw.
Se não pode tratar então deve encapsular a exceção numa exceção própria que pertence À camada em questão. por exemplo PersistenceException , BusinessException ou PresentationException. Vc mesmo cria estas exceções e coloca nos pacotes respectivos. Todas os métodos das classes desses pacotes so podem fazer throw deste tipo de exceção.
Des forma, quando a camada de negocio receber uma exceção de persistência, ela pode tentar resolver o problema, por exemplo dando um roolback no processo. O uexecuntando uma logica alternativa. Se não poder, dve encapsular a exceção numa das suas e passar à frente

E assim vai, até atingir a ultima camada.
Quando chegar nesta camada , deve ser possivel dicidir se a exceção é especifica de tal forma que podemos mostrar uma mensagem ao usuário ou se é generica. Se for expecifica como por exemplo ServerNotFound ou ComunicationImpossible deve ser mostrado ao usuário uma mensagem do tipo “Não foi possivel localizar o servidor, verifique está ligado À internet”
Se for geral apenas “Um erro inexperado aconteceu…” e dar uma sugestão do que fazer.
Ou seja, se o usuário tem uma palavra a dizer na resolusção da exceção ,e ele deve ser avisado em termos compreensiveis do fato. Caso contrario, ele deve ser avisado que não foi possivel resolver o problema.
Antes de passar a excção ao usuário ela deve ser logada (usando o Log4j por exemplo) para futuro inspeção pelo desenvolvedor (se possivel)

Ou seja, vc tem que tratar sim a exceções em todas as camadas, para as resolver ou encapsular para a camada seguinte. Isto pode parecer chato, mas se vc criar algumas classes utilitárias resolve-se facilmente.
Dica: as execções que vc criar deve ser RuntimeException e os métodos mais exteriores da camada (os que são cahamdos pelas outras camadas) devem declarar no throws o tipo de excção de lançam por exmeplo

 public List queryProdutsByID(String id) throws PersistenceException

Olá Sergio, muito obrigado pela resposta, me ajudou realmente a ter uma idéia mais ampla sobre o tratamento de exceções.

Se tiver conhecimento de algum tutorial que trata especificamente sobre o assunto de “arquitetura” das exceções, gostária que me indicasse.

Até, JOhn.

Sempre que possível preserve a stack trace da exception, nunca deixe de tratar uma exception adequadamente.

O melhor tutorial sobre exceptions que conheço é o das blueprints. Postei uma lance sobre exceções no meu blog também:

http://blognotfoundexception.blogspot.com/2006/10/quem-tem-medo-das-excees.html

[quote=“Guilherme Mello”]Sempre que possível preserve a stack trace da exception, nunca deixe de tratar uma exception adequadamente.

O melhor tutorial sobre exceptions que conheço é o das blueprints. Postei uma lance sobre exceções no meu blog também:

http://blognotfoundexception.blogspot.com/2006/10/quem-tem-medo-das-excees.html[/quote]

no fim do texto pode se ler “Dessa forma você não conseguirá rastrear onde está a possível causa do erro. Sempre utilize o método printStackTrace() da classe Throwable:”

O texto e o exemplo passam a ideia de que é correcto invocar o printStackTrace como tratamento de uma excepção. Isto pode induzir muitas pessoas a fazerem isso como procedimento padrão. Esta procedimento é errado. É bom durante os primeiros estágios do aprendizado, mas nunca num programa sério. Esse print stacktrace nunca deve ser invocado pelo programador. Ele sempre deve delegar isso para um codigo de log de exceções. Eu sei que o que querias dizer é que não se deve chamar getMessage pois isso anula o statck trace, mas sugerir que se invoque printstacktrace em vez, deixa a ideia enganosa de que é a forma correta de proceder. Tlv possas clarificar melhor o texto para passar uma ideia mais correcta.

Já agora, no inicio do texto dizes que as execções são subclasses de Exception e que esta é filha de Throwable. PAssando a ideia de que Throwable é uma especia de classe utilitária que nada tem a ver com o problema. Isso tb deixa uma ideia enganosa de que Exception é a classe principal do mecanismo de exceptions. Quando na realidade é a menos importante.
Para compreender exceções o programador java deve entender o mecanismo. O mecanismo é o do lançamento (throw) e captura (catch).
Lançamento do quê ? De Throwable ( throw -> Thowable). Não de Exception.
Ao focar apenas na classe exception, a pessoa inexperiente perde 50% do problema (Error e Throwable)

É possivel fazer catch de Error , ou mesmo de Trowable. Dizem por ai que isso é uma má prática. Bom, como tudo na vida é mau quando usado em demasia. Deve existir pelo menos um lugar onde se faça catch de Error.
Esse lugar deve ser o método mais externo possivel do sistema. Os erros devem ser logados como error no sistema de log., mas nao como fatal. Se possivel o sistema de log deve ser setado para enviar um email quando isso acontece.
A importancia disto é que um erro deriva do um problema no ambiente. E muitas vezes decobrir a causa de algo que o sistema vez errado depende do ambente em que ele está. Se acontecer, por exemplo, um OutOfMemoryError é importante saber, pq diz que precisa ser alocada mais memoria e/ou refactoração do codigo para consumir menos memoria. Mas isto é mais uma questão de logging do que de exception, mas neste caso uma coisa casa com a outra, pois nunca faz sentido logar exceptions para o console. (E dai, como disse antes, nunca faz sentido invocar printStackTrace)

Sergio, você disse que eu devo encapsular as exceções em classes especificas para cada camada:

Digamos que ocorreu um erro em uma das camadas, eu devo fazer um catch de todos os erros e disparar apenas a exceção daquela camada(PersistenceException por exemplo)? dessa maneira como
eu identificaria qual erro aconteceu?

E digamos que eu faça de outra maneira, crie classes filhas de “PersistenceException”, para encapsular os erros especificos… eu não estaria fazendo um novo sistema de
tratamento de exceção ao inves de utilizar o que já esta pronto(do Java)?

Outra possibilidade… Eu criar essa exceção personalizada apenas para encapsular “erros de negócio…”…

Qual é a meneira correta para fazer?

PS: Desculpe por tantas perguntas, é que gostária de fazer o serviço da maneira mais correta.

Muito Obrigado, JOhn. :cool:

Se quando vc diz “erro” se esta a referir a classes que herdam de Error, essas não é para capturar nem trata. (a não ser na camada exteirior como ja expliquei). Se vvc se refere a classes que herdam de Exception ou runtimeException então sim. Deve fazer catch de todos. Isso é simples é só


try {

 // codigo
} catch (Exception e){

   // apanha todos os exception e runtimeexception
}

Quanto à hierarquia. Vc deve crar uma exceção mae para a camada como PersistenceException. Vc pode criar filhas dela, mas apenas para situações que possam ser contornáveis pela camada acima. Não ha pq expecificar o problema se a camada acima não o conseque resolver. Essa decisão vc deve tratar quando captura a exceção. Por exemplo, fileNotFoundException é um exeção que pode ser contornável, por isso ela deve ter a sua ppr execção que especifique qual o arquivo que não foi encontrado. A execção padrão não contem essa informação de forma a poder ser usada depois.
As SQLException é mais complicado. Tem que analizar o codigo da exceção e dicidir. Aqui é boa ideia criar uma classe apenas para tratar SQLException e outra para IOException (se vc usa essa).

Erros de negocio não acontecem na camada de persistencia. Entendeu ? Se está pensando em algum erro de negocio na camada de persistência por favor me diga qual é.

O objetivo não é criar uma hiraequia tã grande como a original. Apenas diferenciar as execções que vc pode realmente tratar em outra camada da s que não. Mas todas elas herdam de uma Exceção genérica da camada.
A camada superior deve analisar , se precisar, o tipo especifico e decidir em cima disso.

Valew kra…

só isso já resolve.

Abraço, JOhn. :cool: