[RESOLVIDO] Exceções com mensagem de erro

10 respostas
P

Fala galera, nao sei nem se estou postando no lugar correto, mas como meu projeto é baseado no vraptor, to postando aqui.
É o seguinte, eu tenho um campo no formulario que ao digitar o codigo e dar um tab, ele preenche o formulario.
Mas quando o código não é encontrado, um erro é lançado no console, mas eu não consigo passar isso para a tela em forma de mensagem de erro.
Alguem tem uma ideia de como fazer isso?
Eu to usando o success, error, complete do $.ajax, mas quando o código não é encontrado simplesmente ele não entra em nenhum destes.
No success, ele não entra no meu else quando o código não é encontrado.
No complete eu pus uns alerts pra ver se ele iria mostrar algo, mas não mostra nada. Taí o código.

controller

@Get("/produtos/buscaid")
	public Produto busca(Long id){
		result.include("id",id);
		return pdao.busca(id);
	}

	@Get("/produtos/buscaid.json")
	public void buscaidJson(Long q){
		try {
			result.use(json()).withoutRoot()
			.from(pdao.busca(q))
			.include("categoria")
			.serialize();
		} catch (Exception e) {
			System.out.println("Produto não encontrado!");			
		}

	}

formulario

$('#id').blur(function(){
			$.ajax({
				url: '<c:url value="/produtos/buscaid.json"/>',
				type: 'GET',
				data: {'q':$('#id').val()},
				dataType: 'json',
				success: function (produto){
					if(produto.nome != null || produto.nome != ''){
						$('#nome').val(produto.nome);
						$('#descricao').val(produto.descricao);
						$('#preco').val(produto.preco);
						$('#categoria_id').val(produto.categoria.id_categoria);
						$('#categoria').val(produto.categoria.descricao);
					} else {
						alert('Produto não encontrado!');
						$('#nome').val('');
						$('#descricao').val('');
						$('#preco').val('');
						$('#categoria_id').val('');
						$('#categoria').val('');
					}			
					},
				error: function(jqXHR, exception) {
		            if (jqXHR.status === 0) {
		                alert('Not connect.\n Verify Network.');
		            } else if (jqXHR.status == 404) {
		                alert('Requested page not found. [404]');
		            } else if (jqXHR.status == 500) {
		                alert('Internal Server Error [500].');
		            } else if (exception === 'parsererror') {
		                alert('Requested JSON parse failed.');
		            } else if (exception === 'timeout') {
		                alert('Time out error.');
		            } else if (exception === 'abort') {
		                alert('Ajax request aborted.');
		            } else {
		                alert('Uncaught Error.\n' + jqXHR.responseText);
		            }
		        },
		        complete: function(produto){
		        	if(produto.nome != null || produto.nome != ''){
		        		alert('teste de acerto!');
		        	}
		        	else {alert('teste de erro!');}
		        }
			});
		});

Obrigado pra quem ajudar :smiley:

10 Respostas

Rafael_Guerreiro

O problema é que você está “matando” a exception…

O ideal é você fazer um log da exception e lançar um JSON que contém o erro… Assim ele volta para o success e lá você o reconhece como erro…

@Get("/produtos/buscaid.json") public void buscaidJson(Long q){ try { result.use(json()).withoutRoot() .from(pdao.busca(q)) .include("categoria") .serialize(); } catch (Exception e) { this.logger.error("Não fez a busca por ID.", e); result.use(json()).withoutRoot().from(new ErrorMessage("Não fez a busca por ID.")).serialize(); // Ou faça um throw e para que ele caia no error method... } }

P

Rafael Guerreiro:
O problema é que você está “matando” a exception…

O ideal é você fazer um log da exception e lançar um JSON que contém o erro… Assim ele volta para o success e lá você o reconhece como erro…

@Get("/produtos/buscaid.json") public void buscaidJson(Long q){ try { result.use(json()).withoutRoot() .from(pdao.busca(q)) .include("categoria") .serialize(); } catch (Exception e) { this.logger.error("Não fez a busca por ID.", e); result.use(json()).withoutRoot().from(new ErrorMessage("Não fez a busca por ID.")).serialize(); // Ou faça um throw e para que ele caia no error method... } }

Obrigado Rafael. Só uma dúvida, a classe logger tem aos montes, ql eu uso :lol: ? E esse ErrorMessage seria uma classe que eu teria que criar?
Obrigado novamente.

Rafael_Guerreiro

O logger funciona assim: Você coloca o log4J na sua LIB (O VRaptor já vem com ele)

Primeiro você precisa configurar o seu arquivo de logs: (DEVE se chamar log4j.properties e DEVE ficar na pasta src do seu projeto)
log4j.rootLogger=WARN,consoleAppender##Aqui são os logs do VRaptor, Hibernate, etc.
log4j.logger.seu.pacote.aqui=DEBUG,dailyFile##Cria um arquivo por dia para o seu log. Coloque o pacote principal do seu projeto...

log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.consoleAppender.layout.ConversionPattern=%-2d{dd/MM/yy HH:mm} %5p %c:%L%n%m%n

log4j.appender.dailyFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyFile.File=${catalina.home}/logs/nomeDoSeuProjeto.log##O log vai ficar na pasta do tomcat dentro de logs e com o nome que você der para ele.
log4j.appender.dailyFile.DatePattern='.'yyyy-MM-dd
log4j.appender.dailyFile.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyFile.layout.ConversionPattern=%-2d{dd/MM/yy HH:mm} %5p %c:%L%n%m%n
ai você importa essas duas classes:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
e coloca isso no começo de TODAS as suas classes (é importante fazer log de tudo, você acaba com o debug... Só vai usar o debug em casos extremos, pois se você fizer log de tudo, o sistema vai sempre te contar o que está acontecendo e qual o erro deu... essas coisas...)
private final Logger logger = LoggerFactory.getLogger(this.getClass());
E depois está pronto para usar:
try {
			logger.debug("Esse é um teste de debug.");
			logger.info("Esse é uma mensagem mais importante que o debug.");
			logger.warn("Essa mensagem é MUITO importante!");
			logger.error("Essa mensagem é primordial!");
		} catch (Exception e) {
			logger.error("Ocorreu um erro.", e); // Você pode passar a exception para ele printar a stacktrace no arauivo. Funciona para todos os outros níveis.
			logger.warn("Ocorreu um erro.", e);
			logger.info("Ocorreu um erro.", e);
			logger.debug("Ocorreu um erro.", e);

			result.use(Results.status())
					.badRequest("Ocorreu um erro."); // Você também pode usar um result de erros para que ele caia no error do ajax...
		}

A classe ErrorMessage você precisa criar... Pode criar uma classe Message que contem 2 atributos, o code e a message... Assim você retorna um JSON quando deu certo:
new Message(200, "Registro inserido com sucesso!");
Ou algum problema:
new Message(500, "Esse registro não pode ser removido!");

P

valeu Rafael, obrigado mesmo.
vou tentar aqui. dessa forma entao vai capturar o erro no success tbm?

Rafael_Guerreiro

Sim… Ai você precisa analisar a variável data…
Se ela tiver um atributo “code” com o valor 500, é por que você mandou uma mensagem de erro… E ai você mostra uma mensagem vermelhinha, essas coisas…

P

Rafael Guerreiro:
Sim… Ai você precisa analisar a variável data…
Se ela tiver um atributo “code” com o valor 500, é por que você mandou uma mensagem de erro… E ai você mostra uma mensagem vermelhinha, essas coisas…

obrigado mesmo, vou testar aqui.

P

Rafael, me tire a ultima e derradeira duvida, por favor!

Fiz aqui tudo que você sugeriu. Mas to com um problema. Eu só consigo pegar um OU outro resultado. Ou seja, ou eu pego o produto, ou a mensagem, nunca os dois. Como eu faço isso? Tentei fazer dois success, um pra cada um, mas ele só pega o ultimo. Então eu tentei colocar os dois na mesma function, mas ele nao reconheceu a mensagem, só se eu criar outro success com message de argumento. Como eu faço pra ele reconhecer os dois? Obrigado

controller

@Get("/produtos/buscaid.json")
	public void buscaidJson(Long q){
		try {
			result.use(json()).withoutRoot()
			.from(pdao.busca(q))
			.include("categoria")
			.serialize();
		} catch (Exception e) {
			this.logger.error("ID não encontrado!", e);  
	        result.use(json()).withoutRoot().from(new Message(500,"ID não encontrado!")).serialize();			
		}
	}

formulario

$('#id').blur(function(){
			$.ajax({
				url: '<c:url value="/produtos/buscaid.json"/>',
				type: 'GET',
				data: {'q':$('#id').val()},
				dataType: 'json',
				success: function (produto, message){
					alert('1 - ' + produto.id + '\n2 - ' + message.code);
					if(produto.nome != null || produto.nome != ''){
						$('#nome').val(produto.nome);
						$('#descricao').val(produto.descricao);
						$('#preco').val(produto.preco);
						$('#categoria_id').val(produto.categoria.id_categoria);
						$('#categoria').val(produto.categoria.descricao);
					}
					if(message.code == 500) {
						alert('Produto não encontrado!');
						$('#nome').val('');
						$('#descricao').val('');
						$('#preco').val('');
						$('#categoria_id').val('');
						$('#categoria').val('');
				}}				
			});
		});
P

alguem pra me ajudar com essa ultima duvida? :smiley:

abraços.

Lucas_Cavalcanti

o que vc quer fazer não é um json válido, por isso não funciona…

de qqer forma nunca vai vir os dois mesmo: ou deu certo e veio o produto, ou deu errado e veio a mensagem…

o que vc pode fazer no success:

.success(function(retorno) {
    if (retorno.code) { // eh uma mensagem
        //algo aqui
    } else { // eh um produto
        //algo aqui
    }
});
P

funcionou, obrigado Lucas. Meu erro estava em querer chamar cada retorno de um nome distinto… usando a mesma variável para os dois, deu certo :smiley:

Valeu!

Criado 9 de novembro de 2012
Ultima resposta 13 de nov. de 2012
Respostas 10
Participantes 3