// add error attributes compliance with servlet spec
ou seja, pra ficar compatível com a api de servlets…
abre uma issue pra ver isso por favor:
se quiser mandar um pull request também seria muito bem vindo =)
// add error attributes compliance with servlet spec
ou seja, pra ficar compatível com a api de servlets…
abre uma issue pra ver isso por favor:
se quiser mandar um pull request também seria muito bem vindo =)
Issue criada:
Pull request criado
Valeu pela ajuda cara!
Abraço.
vulpios, esse erro foi detectado há alguns dias atrás por mim e pelo Lucas. Tenho usado o exception handler tranquilamente com forward, porém redirect ou qualquer outro result é ignorado, estourando na tela.
Teu pull request corrige isso, porém causa um outro problema: se der um erro, eu quero capturar a exception e mostrar na outra tela fazendo um forward. No teu pull request a exception é simplesmente suprimida, então não tenho como exibir mais as mensagens na tela.
Uma sugestão do Lucas é usar outros atributos, que não o javax.servlet.error.exception, pois é ele juntamente com o javax.servlet.error.status_code que dão os erros. Experimente simplesmente comentar essas linhas que você vai notar que tudo funcionará bem.
Vamos fazer uns testes encima do pull request, e depois te aviso.
Abraço
Então Garcia,
Entendemos aqui o comportamento apesar de não concordar com ele.
Fizemos então uma implementação seguindo a ideia do Lucas que você mostrou. No Final ficou assim:
Meu controller
SistemaController
@Post("/sistema/save")
@Override
public void save(Sistema sistema) {
getResult().on(RepositoryExceptionHandler.class).forwardTo(this).saveError();
super.save(sistema);
addSucessMessage("Inclusão efetuada com sucesso");
getResult().redirectTo("/sistema/novo");
}
@Public
@Get
public void saveError(){
addErrorMessage("Erro ao salvar os dados para o novo Sistema");
getResult().redirectTo("/sistema/novo");
}
A classe que sobrescreve o ExceptionHandlerInterceptor
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import br.com.caelum.vraptor.Intercepts;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.core.ExceptionMapper;
import br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor;
import com.google.common.base.Throwables;
/**
* SSOExceptionHandlerInterceptor.java
*
* @author Markus Reichel ? BRQ Java Team
*
* History:
* 29/06/2011 - Markus Reichel
*/
@Intercepts
public class SSOExceptionHandlerInterceptor extends ExceptionHandlerInterceptor{
private final Result result;
private final HttpServletRequest request;
protected static final Logger logger = LoggerFactory.getLogger(SSOExceptionHandlerInterceptor.class);
public SSOExceptionHandlerInterceptor(ExceptionMapper exceptions,
Result result, HttpServletRequest request) {
super(exceptions, result, request);
this.result = result;
this.request = request;
}
@Override
protected void reportException(Exception e) {
Throwable rootCause = Throwables.getRootCause(e);
result.include("sso.javax.servlet.error.exception", rootCause);
result.include("sso.javax.servlet.error.exception_type", rootCause.getClass());
result.include("sso.javax.servlet.error.message", rootCause.getMessage());
result.include("sso.javax.servlet.error.request_uri", request.getRequestURI());
}
}
e o JSP que recebe a mensagem de erro como eu queria e se precisar a exception também
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!--
**************************************************
* *
* Project: SSO - SIGLE SIGN ON - v1.0.0 *
* Author: Jorge Campos *
* Date: 13/06/2012 *
* *
**************************************************
-->
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<title id='Description'>..:: | Sabius - Unimed Fortaleza | ::..</title>
<script type="text/javascript" src="../js/jquery-1.7.2.min.js"></script>
</head>
<body>
<div style="font-color: green;">${responseMessageSuccess}</div>
<div style="font-color: red;">${responseMessageError}</div>
<!-- AQUI EU PEGO O QUE EU QUISER DA EXCEPTION -->
<div style="font-color: red;">${requestScope['sso.javax.servlet.error.exception'].message}</div>
<form name="frm" method="post" action="<c:url value="/sistema/save"/>">
ID: <input type="text" name="sistema.id" value="${sistema.id}"/><br/>
Sistema: <input type="text" name="sistema.nomeSistema" value="${sistema.nomeSistema}"/><br/>
Versão: <input type="text" name="sistema.versao" value="${sistema.versao}"/><br/>
<input type="submit" value="Salvar"/>
<input id="clear" type="button" value="Limpar"/>
<input id="search" type="button" value="Pesquisa"/>
</form>
</body>
Uma ideia interessante seria que vocês mantivessem o comportamento normal do servlet caso nenhuma exceção fosse tratada do jeito que esta, mas caso haja o tratamento o vraptor leria configurações de um properties com essas variáveis onde deveriam setar o exception
do tipo:
javax.servlet.error.exception.equivalent=sso.javax.servlet.error.exception
ou algo parecido ou melhor do que isso aí e no método reportException verificaria a existencia desses properties
Abraço cara!
Valeu pela ajuda.
Porque você não concorda? E como você acha que deve ser?
Minha visão é de quem sempre que ocorra um erro, você deixe as informações dela em algum ponto para que você possa fazer algo como mostrar para o usuário, etc. Um exemplo é que você pode tentar incluir um usuário que já existe, então uma Exception será lançada. Como você irá mostrar a mensagem para o usuário? Com estes atributos no request, basta fazer um requestScope[‘javax.servlet.error.message’] para pegar a exception. Ou no caso de uma errorpage do JSP basta fazer e.getMessage().
Eu gostei muito da idéia do prefixo SSO nos atributos, e acho muito bom assumir algo assim então. Minha sugestão lá no pull request é de colocar então o prefixo vraptor antes do javax.xxxx, o que ficaria algo assim:
result.include("vraptor.javax.servlet.error.exception", rootCause);
result.include("vraptor.javax.servlet.error.exception_type", rootCause.getClass());
result.include("vraptor.javax.servlet.error.message", rootCause.getMessage());
result.include("vraptor.javax.servlet.error.request_uri", request.getRequestURI());
Opa Garcia, minhas desculpas!
Me expressei mal! Não é com a visão que não concordo, essa é fantástica! Adorei a ideia do modo de controlar as exceções, o que não concordei foi com a execução de como ela foi feita, que é de fato o bug.
É uma Excelente ideia utilizar as variáveis com o prefixo vraptor, eu só não retiraria o comportamento normal da especificação do servlet que é como esta! Faria um meio termo entre os dois, pois se não houver tratamento, o erro 500 deve ser mandado para a tela de qualquer jeito!
Abraço.
Fazer set dos atributos javax.servlet.* é somente para quando você trata a exception. Quando você quer que exiba a tela de erro padrão do appserver, basta estourar a exception sem tratamento algum. Isso é o que acontece aqui:
if (!(e.getCause() instanceof Exception) || !replay((Exception) e.getCause())) {
throw e;
}
Abraço