[RESOLVIDO] VRaptor - Erro após commit do plugin hibernate4

Bom dia prezados,

Estou com um problema relacionado ao plugin do VRaptor para Hibernate4.
O problema ocorre quando acontece um erro na transação, que como ocorre após o escopo do controller, eu não consigo tratá-lo.

Por ajax, a resposta é 200, informando um fake success.
Em outras requisições o stack do erro aparece, sem possibilidade de tratá-lo.

Eu cheguei a criar um interceptor pra tratar exceptions que fique antes do interceptor do plugin na pilha de execução, mas ele não serve pra tratar as respostas ajax, já que quando tento adicionar a mensagem não é possível porque ocorre um ResultException pois uma resposta de sucesso já foi criada antes, já que o salvar ocorreu com sucesso (pois como disse: o erro só ocorre no commit).

Não consigo desabilitar o plugin e tratar a transação na mão para estes casos porque o accepts do mesmo é sempre true.
A única forma que consegui fazer é justamente removendo o plugin do classpath e tratar a transação manualmente.

Alguém tem alguma sugestão?

qual result vc está executando?

o que dá pra tentar fazer é deixar ele lazy, só sendo executado de verdade após a transação…

se for um caso específico é mais fácil de resolver =)

especialmente o result json

result.use(json()).from(object).serialize();

o que está ocorrendo é que após criar o result json, ocorre o erro, então tenho que enviar um bad request.
o erro ocorre porque o result já foi criado então não consigo alterá-lo, mesmo com o erro o json é retornado como sucesso, mas ocorreu uma exception e a transação é desfeita.
na teoria, se as regras de validação estiverem consistentes com o banco isto não ocorre, mas se ocorrer qualquer problema de transação é que o problema aparece.

como faz para que ele fique lazy? é possível alterar a mensagem do result após te-lo criado sem exception?

Veja se esse gist resolve seu problema:

basicamente ele escreve o json num StringWriter, e só escreve no response depois de executar o transaction interceptor. Daí se der exception ele não vai escrever no response! Daí vc consegue dar o erro 400 =)

Fala Lucas,

A solução resolveu, só que não consigo mais usar o json pra escrever a mensagem né…
Escrevi com o body do http mesmo =)

Só uma coisa é que o getXStream é deprecated né?

como assim não consegue usar o json?

a idéia é pegar o writer.toString() e jogar no response… (pode ser via result http body sem problemas)

sim o getXStream() está deprecated pq não é mais pra sobrescreverem ele. Mas pode usá-lo sem problemas. Se preferir fazer um inline dele, sem problemas tb.

é que na verdade eu tentei serializar a mensagem de erro e setar o status

result.use(json()).from("erro bla", "error").serialize()

acredito que não funcionaria mesmo já que a mensagem ficou retida no writer e a mensagem que existe lá não me interessa mais.
eu tenho um interceptor que executa antes na cadeia de interceptors onde usei o http body pra imprimir a mensagem no response.

result.use(http())
					.body("erro bla")
					.setStatusCode(HttpStatus.SC_BAD_REQUEST);

assim o result json que imprimiu sucesso não é executado e o http com a mensagem de erro sim
tem uma forma melhor que não entendi?

vc pode tentar:

result.use(status()).badRequest(errors);

ou só:

result.use(status()).badRequest("erro bla");

assim funciona mas ele não está usando json, entá enviando a tela de stack html do status 400 e eu quero só a mensagem, de preferência no mesmo formado do validator pra não ter que tratar de maneira diferente.

eu só consegui fazer assim:

result.use(http())
					.body({errors: {message}})
					.setStatusCode(HttpStatus.SC_BAD_REQUEST);

o accept é application/json
o content-type é form

mas o status code fica certo? vc tá setando ele depois de mexer no body…

o status fica correto sim.
vamos deixar assim mesmo =>

muito obrigado pela ajuda