Vraptor - tratando todos erros no controller

Não quero deixar nenhum erro sem tratamento, na pior das hipóteses colocar o erro numa lista e enviar para a minha view exibir dentro de uma caixinha de erro apropriada.
Algo desse tipo funcionaria?

public void editar(Casa casa) { result.on(Exception.class).include("MSG_ERRO", validator.getErrors()); casaDao.editar(casa); result.include("MSG_SUCESSO", "editar.sucesso"); result.redirectTo(this).pesquisar(casa, "", ""); }
Estou também com um erro que está aparecendo apenas no log, mas não chega ao meu controlador para que eu possa tratar:

É um erro que seria fácil de validar direitinho e tudo, inclusive vou melhorar as validações, mas porque o erro não chega no meu controller? E se fosse outro erro desconhecido qualquer, eu ficaria no escuro tb?
Estou usando o “vraptor-plugin-hibernate4”.

essa exception só vai acontecer no commit da transação (ou qdo a operação for pro banco)… então o único jeito de pegar esse erro no controller seria fazer um try…catch em volta do método que commita a transação…

se isso estiver sendo feito fora do dao, vc pode fazer um session.flush() ou entityManager.flush() pra forçar o erro.

Mas o commit está no HibernateTransactionInterceptor (que inclusive foi você quem programou), eu vou precisar editar essa classe de alguma forma?
Só para esclarecer, quando eu estou tentando cadastrar um valor string com mais caracteres do que o campo do banco está aparecendo a minha mensagem de sucesso, o registro não está sendo gravado, e só aparece erro no log. Eu preciso que apareça um erro na view para que o usuário (ou eu mesmo enquanto ainda estou programando) veja que o registro não foi cadastrado.
Tentei usar o session.flush() mas continua não tratando o erro, preciso colocar o erro dentro de uma caixinha de mensagens, e não que ele tome toda a tela.

[code]org.hibernate.exception.GenericJDBCException: ERROR: current transaction is aborted, commands ignored until end of transaction block
org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
$Proxy330.executeUpdate(Unknown Source)
org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3017)
org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2919)
org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3248)
org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:140)
org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:276)
org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1214)
org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:403)
org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
br.com.caelum.vraptor.plugin.hibernate4.HibernateTransactionInterceptor.intercept(HibernateTransactionInterceptor.java:35)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:93)
br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44)
br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:91)
br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:88)

root cause

org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block
org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062)
org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795)
org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479)
org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:367)
org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:321)
com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:616)
org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
$Proxy330.executeUpdate(Unknown Source)
org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3017)
org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2919)
org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3248)
org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:140)
org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:276)
org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1214)
org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:403)
org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
br.com.caelum.vraptor.plugin.hibernate4.HibernateTransactionInterceptor.intercept(HibernateTransactionInterceptor.java:35)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:93)
br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44)
br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:91)
br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:88)
[/code]

vc fez o session.flush() dentro do dao e não deu a exception?

o que vc pode fazer é parar de usar o controle de transação do VRaptor e configurar o do spring, que deixa vc colocar um @Transactional em volta do dao e daí a exception chegaria no controller…

o problema aqui é que a exception acontece só no interceptor que faz o commit, depois que o método do controller já fez o redirect pra página de sucesso.

Eu dei session.flush() dentro do dao e coloquei throws Exception no metodo. No controller eu faço um try/catch, mas o erro não é tratado, aparece na verdade aquela tela de erro do tomcat no navegador.
DAO: public void editar(T bean) throws Exception { session.update(bean); session.flush(); }
Controller:@Post() public void editar(Casa casa) { try { casaDao.editar(casa); result.include("MSG_SUCESSO", "editar.sucesso"); result.redirectTo(this).pesquisar(casa, "", ""); } catch(Exception e) { List<String> le = new ArrayList<String>(); le.add(e.toString()); result.include("MSG_ERRO", le); } }

O que tá errado? Não era para tratar o erro assim? A pilha de erro nem mostra nada referente às minhas classes…

Quando coloco o try/catch no DAO ele intercepta o erro, mas de lá tem como eu setar a lista de mensagens de erro que é exibida na view? Seria indicado fazer isso?

significa que o session.flush() não tá soltando a exception, então não adianta fazer desse jeito.

tenta criar esse arquivo:

se não funcionar tenta configurar o spring transaction, que nem esse post tá falando:
http://www.guj.com.br/java/276595-vraptor-exception-handling-nao-funcionando#1455854

[RESOLVIDO]
Consegui sem usar essas ultimas dicas que você deu. Passei a mensagem do DAO via Validator ao invés de “throws Exception”.
DAO: public void editar(T bean) { try { session.update(bean); session.flush(); } catch(Exception e) { Message msg = new ValidationMessage(e.toString(), ""); validator.add(msg); } }
Controller:

@Post() public void editar(Casa casa) { casaDao.editar(casa); validator.onErrorRedirectTo(this).carregar(casa); result.include("MSG_SUCESSO", "editar.sucesso"); result.redirectTo(this).pesquisar(casa, "", ""); }