Exception

10 respostas
R

Pessoal, tenho estudado java e ando com algumas dificuldades em relação a tratamento de exceptions.

Estou fazendo um sisteminha, e estou tentando separar as coisas.
As excessões relevantes pro usuario estou tentando passa-las para serem tratadas nas classes referentes a interface grafica, e ai esta o meu problema.

Duvidas:
- Sei que utilizando throws eu afirmo que ali pode ocorrer ‘tal’ excessão e posso trata-la em outro metodo que chama aquele. Isso serve pra qualquer tido de exception?

Estou tentando fazer isso para tratar uma Exception do Hibernate “HibernateException” para mostrar uma mensagem ao usuario de que a conecção com o banco falhou.

  • Ando lendo bastante tambem sobre a possibilidade de eu criar minha propria exception, creio que preciso criar uma classe que extende Exception, e que devo utilizar throw, mas não entendo quando usa-la, e muito menos como fazer uma classe que captura uma exception.

  • Vi um pessoal utilizaqndo algo assim também.

catch(HibernateException e)
{
    throw e;                //Como isso funciona? eu passo ela pra outro método tratar?
}

Alguem pode me ajudar?

10 Respostas

Andre_Fonseca

Rafael_1:
Pessoal, tenho estudado java e ando com algumas dificuldades em relação a tratamento de exceptions.

Estou fazendo um sisteminha, e estou tentando separar as coisas.
As excessões relevantes pro usuario estou tentando passa-las para serem tratadas nas classes referentes a interface grafica, e ai esta o meu problema.

Duvidas:
- Sei que utilizando throws eu afirmo que ali pode ocorrer ‘tal’ excessão e posso trata-la em outro metodo que chama aquele. Isso serve pra qualquer tido de exception?

Estou tentando fazer isso para tratar uma Exception do Hibernate “HibernateException” para mostrar uma mensagem ao usuario de que a conecção com o banco falhou.

  • Ando lendo bastante tambem sobre a possibilidade de eu criar minha propria exception, creio que preciso criar uma classe que extende Exception, e que devo utilizar throw, mas não entendo quando usa-la, e muito menos como fazer uma classe que captura uma exception.

  • Vi um pessoal utilizaqndo algo assim também.

catch(HibernateException e)
{
    throw e;                //Como isso funciona? eu passo ela pra outro método tratar?
}

Alguem pode me ajudar?

Oi,

Basicamente o seu código está capturando uma HibernateException e lançando ela novamente, ou seja, não está engolindo a excessão.
Isso é utilizado muitas vezes quando você quer capturar uma Excessão mais genérica e lançar uma mais específica sua

Dê uma lida aqui

Abs

R

Legal o material, mas tenho uma duvida:

try {
  PreparedStatement stmt = con.prepareStatement(query);
  // ?
} catch (SQLException e) {
  // Epa! SQLException é erro grave, irrecuperável! Pode ter queimado o banco de dados?
  // Não deveria ser checked exception e, além disso, é genérica demais. 
  // Serve para muitos casos!
  throw new AcessoADadosException("Problema na criação do Statement",  e);
  // Agora sim, encapsulei a SQLException na minha exceção específica. 
  // Além disso ela é RuntimeException: unchecked!
}

Quando ele fez new AcessoADadosException(“Problema na criação do Statement”, e);

ele disse que a exception agora é mais especifica, mas como ele consegue saber qual é a causa do problema dentro da classe AcessoADadosException?

o que percebi é que o argumento"e" é passado como parametro.

peczenyj

Se vc passa a exception que aconteceu como argumento do seu construtor, tem uma chance dessa classe fazer alguma coisa com essa informação.

Por exemplo, uma SQLException possui um método getErrorCode que retorna um número que pode servir para vc identificar alguma coisa de acordo com o seu banco de dados.

http://java.sun.com/j2se/1.4.2/docs/api/java/sql/SQLException.html

Andre_Fonseca

Rafael_1:
Legal o material, mas tenho uma duvida:

try {
  PreparedStatement stmt = con.prepareStatement(query);
  // ?
} catch (SQLException e) {
  // Epa! SQLException é erro grave, irrecuperável! Pode ter queimado o banco de dados?
  // Não deveria ser checked exception e, além disso, é genérica demais. 
  // Serve para muitos casos!
  throw new AcessoADadosException("Problema na criação do Statement",  e);
  // Agora sim, encapsulei a SQLException na minha exceção específica. 
  // Além disso ela é RuntimeException: unchecked!
}

Quando ele fez new AcessoADadosException(“Problema na criação do Statement”, e);

ele disse que a exception agora é mais especifica, mas como ele consegue saber qual é a causa do problema dentro da classe AcessoADadosException?

o que percebi é que o argumento"e" é passado como parametro.

O AcessoADadosException pode ser uma exceção de negócio que você mesmo criou, e a idéia é que ele seja específica de um erro de negócio próprio do sistema. O ideal é você ter quantas exceções forem necessárias para cobrir a maioria dos casos de erro que o seu sistema possui. O e é passado para frente para que quando você for acompanhar o log possa ter também a excessão que originou a sua.

Por exemplo

catch (SQLException e) if (e.getErrorCode() == 200458) { throw new InserindoClienteException("Erro ao tentar inserir um cliente",e); } else if (e.getErrorCode() == 200100) { throw new AtualizandoClienteException("Erro ao tentar atualizar os dados do cliente",e); } }

Abs

R

Humm, legal em cara.

tenho esse metódo que retorna uma lista de cadastros.

public List CarregaTodas() 
    {
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Criteria criteria = session.createCriteria(Placa.class);  
        criteria.addOrder(Order.asc("id"));  
        return criteria.list();       
        
            
    }

supondo que aconteceu um problema no meu servidor de banco de dados mysql, e eu quero avisar o usuario que houve um erro na conecção.

eu adiciono um throws HibernateException no cabeçalho? para poder trata-lo mais acima na pilha de chamada?

eu estou fazendo isso, tenho três classes que fazem referencia a ela.

ex:

getBuffer() chama diretamente o metódo.

inicia_e_valida() chama getBuffer()

e tenho a classe referente a GUI, que chama inicia_e_valida.

eu tentei ir colocando throws em todos os metodos que faz referencia ao CarregaTodas(), mas ela acaba não sendo capturada quando faço isso até a classe GUI, é nisso que estou me enroscando.

Andre_Fonseca

Seria algo parecido com isso:

carregaTodas() throws HibernateException {
    ...
    catch (HibernateException he) {
      log.error("Erro ao carregar todas",e);
      throw new ExceptionType1("Erro ao carregar todas",e); 
    }	
} 

getBuffer() throws ExceptionType1 {
    ...
    catch (ExceptionType1 e1) {
      log.error("Erro getBuffer",e1);
      throw new ExceptionType2("Erro getBuffer",e1); 
    }	
}

inicia_e_valida() throws ExceptionType2 {
    ...
    catch (ExceptionType1 e2) {
      log.error("inicia_e_valida",e2);
      metodoQueFazORollbackSeNecessario();
    }	
}

O HibernateException deve ser lançado apenas pelo método que utiliza o Hibernate, o metodoQueFazORollbackSeNecessario() deve - se necessário - ser chamado no catch no topo da sua pilha de exceções, quando você não precisa mais lançar para ninguém tratar..

Não sei se você tá utilizando mas dê uma olhada no log4j que pode te ajudar bastante na hora de debugar a aplicação..

Abs

R

Pessoal, no Hibernate existe algum tempo limite pra ficar tentando a conecção?

Estou debugando aqui, quando paro o serviço do banco, o hibernate fica tentando a conecção e demora uma eternidade para retornar a excessão.

Não consegui ainda jogar a excessão pro usuario da forma que eu gostaria.

vou colocar a classe que criei.

package PersistenceExceptions;

import org.hibernate.HibernateException;



/**
 *
 
 */
public class ServiceException extends RuntimeException
{
    private static String message;
    
    public ServiceException(HibernateException e)
    {
        super("Erro - Serviço de Banco de Dados:\n "+e.getMessage()+"\n\nContate o Suporte!");
        message =  "Erro - Serviço de Banco de Dados:\n "+e.getMessage()+"\n\nContate o Suporte!";
        
       
      
    }
    
    public ServiceException()
    {
        super("Erro - Serviço de Banco de Dados\nEntre em contato com o Suporte!");
    }

    public void ObterMessagem()
    {
        javax.swing.JOptionPane.showMessageDialog(null, message, "Erro", javax.swing.JOptionPane.ERROR_MESSAGE);
    }

}

A excessão ocorre aqui, eu quero ir jogando ela entre os metós que fazem referencia a ela, para serem tratadas lá emcima.
Fiz desta forma:

public List CarregaTodas() throws ServiceException
    {
        try
        {                       
            Session session = HibernateUtil.getSessionFactory().openSession();
            Criteria criteria = session.createCriteria(Placa.class);  
            criteria.addOrder(Order.asc("id"));  
            return criteria.list();       
        }
        catch(HibernateException e)
        {
            throw new ServiceException(e);
        }
        
    }
/*Metodo utilizado para retornar Lsita atualizada de placas
    */    
    public ArrayList RetornaBufferTodas() throws ServiceException 
    {      
        try
        {
              HibernateFactoryDAO factory = new HibernateFactoryDAO();
                 
              List<Placa> aux = factory.criaPlacaDAO().CarregaTodas();
                
              todas = (ArrayList)aux; 
    
               return todas;
        
        }catch(ServiceException e)
        {
            
            throw e;            
                
        }
public void pegaListaAtualizada() throws ServiceException
    {
       try
       {
            this.todas = (ArrayList)RetornaBufferTodas();
       }catch(ServiceException e)
       {
           throw e;
       }
    }

e assim por diante…

Isso funciona? eu quero pegar a excessão do hibernate trata-la e jogar pro usuario, tá dificil.

Andre_Fonseca

Oi Rafael,

Dá uma olhada neste tópico

Abs

R

cara, consegui resolver os problemas. Muito obrigado pelas dicas.

Mas tenho uma utima duvida, estou utilizando uma linha de execução (Thread) para processar alguns metodos que chamo na abertura da janela.

public void run() throws ServiceException
    {
       try
       {
           todas.pegaListaAtualizada();
           boolean status = this.iniciaEvalidaTimerInterrogacao();
     
           if(status = false)
           {
               throw new CachePlacasException();
           }   
           
       }catch(ServiceException e)
       {
          throw e;
       
       }catch(Exception e)
       {
           System.out.println("Erro" + e);
       }

Eu gostaria de jogar a excessão ServiceException para ser tratada no método chamador,

Tenho um método atualizaCachedePlacas().

public void AtualizaCachedePlacas() throws ServiceException
     {
           try
           {
                threadAtualizaCache = new Thread(this);
                threadAtualizaCache.start();
           
           }catch(ServiceException e)
           {
              throw e;
           }
     }
}

O problema é que a mensagem que eu trataria mais acima, mostrando a mensagem pro usuario através de um dialog não é exibida no dialog e sim no prompt.
dentro da classe de tratamento de exception que criei tenho o metodo getMessage que já faz isso em uma caixa de dialog.

o tratamento de excessões dentro de um método run é diferente?

Andre_Fonseca

oi,

o método run não deve lançar excessão, já que ele é apenas alguém que chama outro alguém que faz alguma coisa… tente dar uma olhada no log4j assim você poderá usar um FileAppender, e jogar o log para arquivo ao invés do console

abs

Criado 8 de setembro de 2008
Ultima resposta 12 de set. de 2008
Respostas 10
Participantes 3