Lucas, o problema de usar referer é que se der um erro e eu ir pro referer funciona da primeira vez. Mas se der um erro de novo meu referer é a própria página de erro, assim você entra em loop infinito.
A solução do Sérgio é boa para erros que você não consegue mais recuperar a aplicação, exemplo, banco fora do ar e afins.
Mas quando dá erros de regra de negócio ou até mesmo o estouro de uma constraint, o que você faz? Exibir uma página padrão é muito ruim, pois você tem que fazer o usuário clicar em voltar e você ainda precisa cuidar para trazer os dados de novo. Em muitos casos history.back não serve. O mais ideal, na minha visão, é você voltar para alguma tela e exibir alguma mensagem que explique o que aconteceu.
Exemplo: estou na tela de edição do usuário, então quando eu vou salvar o objeto ocorre um erro de lock otimista. O que eu vou fazer? Volto para a tela de edição do usuário, exibo a mensagem “Versão do objeto inválida”. Assim ao mesmo tempo eu mostro a mensagem do erro e o usuário já está na própria tela de edição. Imagina que saco você mandar o usuário para uma página em branco dizendo “Versão do objeto inválida” e apenas isso? Aí ele tem que voltar por conta própria, além de você ter um processamento de tela e requisição a mais.
Obvio que você pode fazer try and catch para tratar os erros que vêm da regra de negócio, mas pense o quão trabalhoso seria fazer isso em uma aplicação do tamanho da que eu tenho, que são aproximadamente 350 controllers.
Achei que nesse ponto ficou um espaço vazio no vraptor. Por isso há algum tempo eu tenho corrido atrás de implementar isso, que consegui com a tua ajuda. FIz algo baseado no Struts 1x (que eu gostava muito), onde você diz antes de tudo para onde ir caso der um erro, e se der erro ele vai para tal tela.
Eu estarei muito ocupado até os dias do sun tech days, mas logo após isso vou passar um gist com meu exception handlers e te passo. Há uns detalhes que ainda estou revendo nesse exception handler, mas tudo culpa do waffle 
