VRaptor 3 - tratamento de erro nas aplicações

Chegaram a alguma conclusão sobre qual seria a melhor maneira de tratar uma exceção no VRaptor?

depende da exceção…

se é uma exceção inesperada (geralmente as runtime) mostrar uma página de erro genérica mesmo (aquela configurada no web.xml)

se é uma exceção que faz parte da sua lógica de negócios, você pode mostrar uma página diferente pro usuário, ou incluir uma mensagem de validação.

Lucas,

Eu trabalho com o VRaptor em uma aplicação com o Flex.
Então, a exceção precisa ser disparada para chegar no RemoteObject como faultEvent. Eu não tenho como redirecionar para um página do navegador, ou usar a página de erro do web.xml

Se eu usar o result.onErrorUse ele vai me redirecionar para outra página ou tenho como disparar um outro erro com uma mensagem?

Exemplo:

result.onError(Exception.class).throws(FlexException.class).withMessage(“Ocorreu um erro não reconhecido”);

ou

result.onError(Exception.class).throws(new FlexException(“Ocorreu um erro não reconhcido”);

dá pra fazer isso sim… crie a classe/interface:

interface ExceptionView extends View {
    void doThrow(Exception e);
}
// implementação anotada com @Component

e vc pode fazer:

result.onError(Exception.class).use(ExceptionView.class).doThrow(...);

Preciso criar uma “ExceptionView” para cada tipo de exceção que capturar? Ou crio uma vez só?

uma só.

Essa classe não poderia fazer parte do projeto? (só uma sugestão)

do VRaptor, você diz? A gente pode criar um plugin pra isso.

é… se é a mesma classe para todo projeto… penso que ela poderia fazer parte do projeto vraptor-core

na verdade, se você vai fazer isso genericamente eu colocaria esse código num interceptor, com try catch mesmo.

para ir para lugares diferentes já existe o result.onError(), ou transformar exceções em erros de validação.

ok vou fazer alguns testes aqui.

vou usar um interceptor para as exceções genéricas e o result para as específicas.
acho que vai funcionar como o esperado…

valeu!

package br.com.xxxx.infra;

import br.com.caelum.vraptor.View;

public interface ExceptionView extends View
{
    void doThrow(Exception e);
}

Como ficaria a implementação?

[code]@Component
public class ClasseQualquer implements ExceptionView
{

   @Override
public void doThrow(Exception e) 
{
	//o que vai aqui??
}

}[/code]

aí vc coloca o que vc quer que aconteça… pelo nome do método chutaria algo como:

throw e;

Mas ai eu só posso disparar RuntimeException se eu quiser pegar no Interceptor igual você me sugeriu.
Se for Exception eu vou precisar tratar o throws do método doThrow, certo?
Ela não vai chegar até a camada Flex.

Interceptor:

public void intercept(InterceptorStack stack, ResourceMethod method, Object instance) { Transaction transaction = null; try { transaction = sessao.beginTransaction(); stack.next(method, instance); transaction.commit(); } catch(GenericJDBCException ex) { result.on(GenericJDBCException.class).use(ExceptionView.class).doThrow(new FlexException("xxx", ex)); } catch(Exception ex) { result.on(Exception.class).use(ExceptionView.class).doThrow(new FlexException("xxxx", ex)); } finally { if (transaction != null && transaction.isActive()) { transaction.rollback(); } } }

Desculpa, agora que eu vi, posso fazer um throw new no Interceptor?

public void intercept(InterceptorStack stack, ResourceMethod method, Object instance) { Transaction transaction = null; try { transaction = sessao.beginTransaction(); stack.next(method, instance); transaction.commit(); } catch(GenericJDBCException ex) { throw new FlexException("xxxx.", ex); } catch(Exception ex) { throw new FlexException("xxxx", ex); } finally { if (transaction != null && transaction.isActive()) { transaction.rollback(); } } }

Pois é, essa era a minha sugestão :wink: Pode fazer isso sim.

Pessoal…estou apanhando muito aqui, estou tentando fazer basicamente a mesma coisa, só que NUNCAAA cai no meu catch do Interceptor…

Dou um throw new Exception, ou uma exceção que eu criei, throw new BusinessException, mas de forma alguma cai no catch…

Só lança no meu console a exceção e a mensagem - java.lang.Exception: mensagem…

Alguém sabe como deve ser feito???

Muito obrigado!!

o try…catch está em volta do stack.next?

o interceptor está anotado com @Intercepts?

O erro deve estar acontecendo, pois se uma exceção é pega durante um intercept o VRaptor dispara um exceção personalizada, envelopando a exceção principal. Se eu não me engano é VRaptorInterceptorException…

Faz um catch mais generico Exception e ve qual o tipo de exceção que está sendo disparada.

Oi gente, será que vocês podem me dar uma luz nesse erro?

as minhas classes são

DiscoController

package br.com.caelum.vraptor.blank;

import java.util.List;

import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;

@Resource
public class DiscoController {
	
	private RepositorioDeDisco discos;
	private Validator validator;
	private Result result;

	public DiscoController(RepositorioDeDisco discos, Result result, Validator validator){
		this.discos = discos;
		this.result = result;
		this.validator = validator;
	}
	
	/*
	 * http://localhost:8080/vraptor-discos/disco/formulario
	 */
	public void formulario(){}
	
	@Post
	public void adicionar(final Disco disco){
	}
	
	/*
	 * http://localhost:8080/vraptor-produtos/disco/lista
	 */
	public List<Disco> lista(){
		return null;
	}
	
	/*
	 * http://localhost:8080/vraptor-produtos/disco/exibe
	 */
	public void exibe(Long id){}
	
	public void telaAnteriorAltera(Long id){}
	
}

a DiscoDAO

package br.com.caelum.vraptor.blank;

import java.util.ArrayList;
import java.util.List;

public class DiscoDAO implements RepositorioDeDisco {
	
	private static List<Disco> DISCOS = new ArrayList<Disco>();
	
	static {
		popinicia();
	}
	
	public List<Disco> lista(){
		return DISCOS;
	}
	
	private static void popinicia(){
		DISCOS.add(new Disco("Syncronicity"));
		DISCOS.add(new Disco("Bessies Blues"));
		DISCOS.add(new Disco("Wes Montgomery"));
		DISCOS.add(new Disco("mine"));
	}

	public void salva(Disco disco) {
		DISCOS.add(disco);
	}

	public List<Disco> pegaTodos() {
		return DISCOS;
	}

	public void remove(Disco disco) {
		DISCOS.remove(disco);
	}

	public Disco pegaPorId(Long id) {
		for(Disco disco : DISCOS) {
			DISCOS.remove(id);
			if(disco.getId().equals(id)) return disco;
		}
		return null;
	}

	public void altera(Disco disco) {
		DISCOS.add(disco);
	}
}

RepositorioDeDisco

[code]
package br.com.caelum.vraptor.blank;

import java.util.List;

public interface RepositorioDeDisco {

void salva(Disco disco);
List<Disco> pegaTodos();
void remove(Disco disco);
Disco pegaPorId(Long id);
void altera(Disco disco);

}[/code]

package br.com.caelum.vraptor.blank;

public class Disco {
	
	private static int i;	
	private Integer id;
	private String nome;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}
	
	public Disco(String nome){
		i++;
		this.id = i;
		this.nome = nome;
	}
}

Será que os senhores podem me ajudar?