Como apresentar página de erro

5 respostas
T

Olá gente.

Estou desenvolvendo um projeto em JSF 2.0 com Primefaces.
Chegou a hora de tratar os erros e eu não estou conseguindo capturá-los.
Forcei o erro ao deletar um registro de uma tabela, porém o erro ocorre, mas eu não consigo capturar para apresentar a mensagem.

O meu bean tem o seguinte método:

public void excluir(){
		if (empresa != null){
			try{
				Session session = HibernateUtil.currentSession();
				EmpresaDao empDao = new EmpresaDao(session);
				empDao.delete(empresa);
				empresa = null;
			}catch (Exception e){
				FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Erro ao excluir Parceiro: ", e.getMessage()));
			}
		}
	}

Ao debugar, passou tranquilo sem gerar exception, porém não deletou o registro (óbivio), e gerou o seguinte erro no console do eclipse:

SEVERE: Servlet.service() for servlet Faces Servlet threw exception
java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`tigre`.`taboperacao`, CONSTRAINT `fk_TabOperacao_TabEmpresa` FOREIGN KEY (`empresaId`) REFERENCES `tabempresa` (`empresaId`) ON DELETE NO ACTION ON UPDATE NO ACTION)
	at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2015)
	at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1451)
	at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
	at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
	at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:64)
	at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:1175)
	at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1699)
	at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
	at br.com.titvs.ind.model.EmpresaDao.tableList(EmpresaDao.java:47)
	at br.com.titvs.ind.control.EmpresaBean$1.fetchLazyData(EmpresaBean.java:125)
       ...

Alguém pode me dar um luz de como pegar esse erro e colocar no messages?

5 Respostas

T

Poxa…

Ninguém vai me ajudar?

francis.junio

Na sua pagina que vc esta esperando o erros tem as tags de messages?

T

Olá Francis,

tem sim…
Eu usei a tag do componente primefaces <p:messages>.
Mas percebi que o erro está sendo capturado pelo HibernateSessionFilter que gera um ServletException. Ou seja ele não vai ocorrer método acionado por actionLitener, pois vais ser executado nele, só que vai ser comitado pelo filtro.
eu acabei mudando o tratamento de erro para configuração do web.xml, adicionando tag , que também me deu a maior dor de cabeça, mas se encaminha para o sucesso. Por sinal já vi que você está me dando uma força lá também…
Se você souber como pegar a exceção no HibernateSessionFilter e jogar na <p:messages> da pagina que gerou o erro, vou ficar em estado de graça. rsrsrsrsr

Obrigado Francis

francis.junio

Olha vei… eu uso o Richfaces e esse primefaces eu nunca usei… Vou te dar um exemplo do meu negocio aqui que ta funcionando corretamente…

public String save() {		
		try {
			//minha regra....
			
		} catch (Exception e) {
			Messages.severityFatal(e.getMessage());
			return "failed";
		}
		
		return "success";
	}

Eu tenho uma classe que lança as mensagens para o Faces para mim…
Na excessao eu so chamo essa classe, e chamo o metodo responsavel por mandar a mensagem com o severity que preciso passando a mensagem.

public static void severityFatal(final String summary) {
		if (!mensagemJaInserida(summary)) {
			FacesContext.getCurrentInstance()
					.addMessage(
							"",
							new FacesMessage(FacesMessage.SEVERITY_FATAL,
									summary, null));
		}
	}

private static boolean mensagemJaInserida(String message) {
		Iterator<FacesMessage> mensagens = FacesContext.getCurrentInstance()
				.getMessages();
		while (mensagens.hasNext()) {
			String msg = mensagens.next().getSummary();
			if (msg.equals(message)) {				
				return true;
				
			}
		}
		return false;
	}

Vê se isso ai te ajuda cara…

T

Obrigado Fancis,

Só que no meu caso o commit é feito no HibernateSessionFilter como segue abaixo:

import javax.servlet.Filter;  
import javax.servlet.FilterChain;  
import javax.servlet.FilterConfig;  
import javax.servlet.ServletException;  
import javax.servlet.ServletRequest;  
import javax.servlet.ServletResponse;  

public class HibernateSessionFilter implements Filter{  
  
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		try {
			HibernateUtil.openSession();
			HibernateUtil.currentSession().beginTransaction();
			chain.doFilter(request, response);
			HibernateUtil.currentSession().getTransaction().commit();
		}
		catch (Exception e) {
			throw new ServletException(e);
		} finally {
			HibernateUtil.closeCurrentSession();
		}
	}
	public void init(FilterConfig ftConfig) throws ServletException {
	}
	public void destroy() {
	}
}

E não no método acionado pela interface.
Dessa forma o erro será enviado para a aplicação não pela instrução do banco de dados.

Eu criei um Session Bean chamado erroBean e estou com duas propriedade uma para mensagem da exceção capturada e outra para a operação informações que tentou realizar a instrução.
Eu atualizo informo a mensagem do Bean antes de excluir por exemplo e como se trata de um Session Bean a página de erro mostra o erro adequado.

Dá uma olhada a baixo e se for o caso me aponta as não conformidades que você achar:

package br.com.titvs.ind.control;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name="erroBean")
@SessionScoped
public class ErroBean {
	private String operacao;
	private String textoOperacao;
	private String textoExcecao;
	public String getOperacao() {
		return operacao;
	}
	public void setOperacao(String operacao) {
		this.operacao = operacao;
	}
	public String getTextoOperacao() {
		return textoOperacao;
	}
	public void setTextoOperacao(String textoOperacao) {
		this.textoOperacao = textoOperacao;
	}
	public String getTextoExcecao() {
		return textoExcecao;
	}
	public void setTextoExcecao(String textoExcecao) {
		this.textoExcecao = textoExcecao;
	}
}

segue abaixo o código da operação de exclusão de registro:

public void excluir(){
		FacesContext fc = FacesContext.getCurrentInstance();
		HttpSession session = (HttpSession) fc.getExternalContext().getSession(true);
		ErroBean erroBean = (ErroBean) session.getAttribute("erroBean");
		if (erroBean == null)
			erroBean = new ErroBean();
		if (empresa != null){
			Session hs = HibernateUtil.currentSession();
			EmpresaDao empDao = new EmpresaDao(hs);
			erroBean.setOperacao("Excluindo a empresa " + empresa.getNome());
			erroBean.setTextoOperacao("Verifique se não há registro vinculados ao pareceiro selecionado!");
			empDao.delete(empresa);
			empresa = null;
		}
	}

Alterando doFilter do HibernateSessionFilter como segue abaixo:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		try {
			HibernateUtil.openSession();
			HibernateUtil.currentSession().beginTransaction();
			chain.doFilter(request, response);
			HibernateUtil.currentSession().getTransaction().commit();
		}
		catch (Exception e) {
			FacesContext fc = FacesContext.getCurrentInstance();
			HttpSession session = (HttpSession) fc.getExternalContext().getSession(true);
			ErroBean erroBean = (ErroBean) session.getAttribute("erroBean");
			if (erroBean == null){
				erroBean = new ErroBean();
				erroBean.setOperacao("Operação Inválida");
				erroBean.setTextoOperacao("Operação desconhecida no Banco de Dados");
			}
			erroBean.setTextoExcecao(e.getMessage());
			throw new ServletException(e);
		} finally {
			HibernateUtil.closeCurrentSession();
		}
	}

Na minha tela de erro eu coloco as tags <h:outputText value="#{erroBean.operacao}"> <h:outputText value="#{erroBean.textoOperacao}"> <h:outputText value="#{erroBean.textoExcecao}">.

O Bacana dessa solução é que eu só preciso de uma tela de erros operacionais para todas as operações que envolvam Hibernate. Mas tanto você quanto quem mais ler esse post, podem criticar o que achar errado.

Abraços Francis

Criado 14 de agosto de 2010
Ultima resposta 18 de ago. de 2010
Respostas 5
Participantes 2