tratamento de erros do jQuery Ajax, mostrar as mensagens de excepção personalizadas
por exemplo, se quiser abrir uma excepção no lado do Servidor via Struts por throw new ApplicationException("User name already exists");
, quero apanhar esta mensagem ('o nome de utilizador já existe') na mensagem de erro do jQuery AJAX.
jQuery("#save").click(function () {
if (jQuery('#form').jVal()) {
jQuery.ajax({
type: "POST",
url: "saveuser.do",
dataType: "html",
data: "userId=" + encodeURIComponent(trim(document.forms[0].userId.value)),
success: function (response) {
jQuery("#usergrid").trigger("reloadGrid");
clear();
alert("Details saved successfully!!!");
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
}
});
No segundo alerta, onde alerta o erro lançado, estou a receber undefined
e o código de Estado é 500.
Não tenho a certeza para onde estou a ir mal. O que posso fazer resolver este problema?
20 answers
Response.Write
, depois use...
xhr.responseText
...No teu javascript.
Controlador:
public class ClientErrorHandler : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
var response = filterContext.RequestContext.HttpContext.Response;
response.Write(filterContext.Exception.Message);
response.ContentType = MediaTypeNames.Text.Plain;
filterContext.ExceptionHandled = true;
}
}
[ClientErrorHandler]
public class SomeController : Controller
{
[HttpPost]
public ActionResult SomeAction()
{
throw new Exception("Error message");
}
}
Ver programa:
$.ajax({
type: "post", url: "/SomeController/SomeAction",
success: function (data, text) {
//...
},
error: function (request, status, error) {
alert(request.responseText);
}
});
Serversida:
doPost(HttpServletRequest request, HttpServletResponse response){
try{ //logic
}catch(ApplicationException exception){
response.setStatus(400);
response.getWriter().write(exception.getMessage());
//just added semicolon to end of line
}
}
ClientSide:
jQuery.ajax({// just showing error property
error: function(jqXHR,error, errorThrown) {
if(jqXHR.status&&jqXHR.status==400){
alert(jqXHR.responseText);
}else{
alert("Something went wrong");
}
}
});
Tratamento Genérico De Erros Do Ajax
Se eu precisar de fazer um tratamento genérico de erros para todos os pedidos do ajax. Eu vou definir o controlador ajaxError e exibir o erro em um div chamado errorcontainer no topo do conteúdo html.
$("div#errorcontainer")
.ajaxError(
function(e, x, settings, exception) {
var message;
var statusErrorMap = {
'400' : "Server understood the request, but request content was invalid.",
'401' : "Unauthorized access.",
'403' : "Forbidden resource can't be accessed.",
'500' : "Internal server error.",
'503' : "Service unavailable."
};
if (x.status) {
message =statusErrorMap[x.status];
if(!message){
message="Unknown Error \n.";
}
}else if(exception=='parsererror'){
message="Error.\nParsing JSON Request failed.";
}else if(exception=='timeout'){
message="Request Time out.";
}else if(exception=='abort'){
message="Request was aborted by the server";
}else {
message="Unknown Error \n.";
}
$(this).css("display","inline");
$(this).html(message);
});
Tens de converter o responseText
para JSON. Utilizar JQuery:
jsonValue = jQuery.parseJSON( jqXHR.responseText );
console.log(jsonValue.Message);
Se fizer uma chamada para asp.net, isto irá devolver o título da mensagem de erro:
Não fui eu que escrevi toda a mensagem formatErrorMessage, mas acho-a muito útil.function formatErrorMessage(jqXHR, exception) {
if (jqXHR.status === 0) {
return ('Not connected.\nPlease verify your network connection.');
} else if (jqXHR.status == 404) {
return ('The requested page not found. [404]');
} else if (jqXHR.status == 500) {
return ('Internal Server Error [500].');
} else if (exception === 'parsererror') {
return ('Requested JSON parse failed.');
} else if (exception === 'timeout') {
return ('Time out error.');
} else if (exception === 'abort') {
return ('Ajax request aborted.');
} else {
return ('Uncaught Error.\n' + jqXHR.responseText);
}
}
var jqxhr = $.post(addresshere, function() {
alert("success");
})
.done(function() { alert("second success"); })
.fail(function(xhr, err) {
var responseTitle= $(xhr.responseText).filter('title').get(0);
alert($(responseTitle).text() + "\n" + formatErrorMessage(xhr, err) );
})
O tipo de retorno do controlador é satisfatório.
public ContentResult DoSomething()
{
if(somethingIsTrue)
{
Response.StatusCode = 500 //Anything other than 2XX HTTP status codes should work
Response.Write("My Message");
return new ContentResult();
}
//Do something in here//
string json = "whatever json goes here";
return new ContentResult{Content = json, ContentType = "application/json"};
}
E do lado do cliente é assim que a função ajax se parece
$.ajax({
type: "POST",
url: URL,
data: DATA,
dataType: "json",
success: function (json) {
//Do something with the returned json object.
},
error: function (xhr, status, errorThrown) {
//Here the status code can be retrieved like;
xhr.status;
//The message added to Response object in Controller can be retrieved as following.
xhr.responseText;
}
});
Se alguém está aqui como em 2016 para a resposta, use .fail()
para o tratamento de erros como .error()
está desactualizado a partir de jQuery 3.0
$.ajax( "example.php" )
.done(function() {
alert( "success" );
})
.fail(function(jqXHR, textStatus, errorThrown) {
//handle error here
})
espero que ajude
Uma solução geral / reutilizável
Esta resposta é fornecida para referência futura a todos aqueles que se deparam com este problema. A solução consiste em duas coisas:
-
excepção personalizada
ModelStateException
Isso é jogado quando a validação falha no servidor (model state reports validation errors when we use data annotations and use strong typed controller action parameters) -
filtro personalizado de erro de Acção do controlador
HandleModelStateExceptionAttribute
que captura uma excepção personalizada e devolve o estado de erro HTTP com o erro de Estado do modelo no corpo
success
e error
.
Código do lado do cliente
$.ajax({
type: "POST",
url: "some/url",
success: function(data, status, xhr) {
// handle success
},
error: function(xhr, status, error) {
// handle error
}
});
Código do lado do servidor
[HandleModelStateException]
public ActionResult Create(User user)
{
if (!this.ModelState.IsValid)
{
throw new ModelStateException(this.ModelState);
}
// create new user because validation was successful
}
Todo o problema está detalhado em Este post onde você pode encontrar todo o código para executar isso em sua aplicação.
error: function (response) {
var r = jQuery.parseJSON(response.responseText);
alert("Message: " + r.Message);
alert("StackTrace: " + r.StackTrace);
alert("ExceptionType: " + r.ExceptionType);
}
Mudar a estrutura JSON de:
{welcome:"Welcome"}
To:
{"welcome":"Welcome"}
Eu acredito que o controlador de resposta Ajax usa o código de estado HTTP para verificar se houve um erro.
Por isso, se você apenas lançar uma excepção Java no seu código do lado do servidor, mas então a resposta HTTP não tem um código de 500 status jQuery (ou, neste caso, provavelmente o objeto XMLHttpRequest) irá apenas assumir que tudo estava bem.
Estou a dizer isto porque tive um problema semelhante em ASP.NET onde eu estava jogando algo como uma Argumentexcepção("não sei o que fazer fazer...") mas o manipulador de erros não estava disparando.Depois ajustei o {[[0]} para 500 ou 200, quer tivesse ou não um erro.
$.ajax({
url: "controller/action",
type: 'POST',
success: function (data, textStatus, jqXHR) {
var obj = jQuery.parseJSON(jqXHR.responseText);
notify(data.toString());
notify(textStatus.toString());
},
error: function (data, textStatus, jqXHR) { notify(textStatus); }
});
$("#save").click(function(){
$("#save").ajaxError(function(event,xhr,settings,error){
$(this).html{'error: ' (xhr ?xhr.status : '')+ ' ' + (error ? error:'unknown') + 'page: '+settings.url);
});
});
Tens um objecto JSON da excepção lançado, no objecto xhr. Basta usar
alert(xhr.responseJSON.Message);
O objecto JSON expõe duas outras propriedades: 'ExceptionType' e'StackTrace'
error:function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
Tais como
success: function(data){
// data is object send form server
// property of data
// status type boolean
// msg type string
// result type string
if(data.status){ // true not error
$('#api_text').val(data.result);
}
else
{
$('#error_text').val(data.msg);
}
}
Abrir uma nova excepção no servidor usando:
Resposta.StatusCode = 500
Resposta.StatusDescription = ex.Mensagem ()
Acredito que a lista de Estado é devolvida à chamada Ajax...
Exemplo:
Try
Dim file As String = Request.QueryString("file")
If String.IsNullOrEmpty(file) Then Throw New Exception("File does not exist")
Dim sTmpFolder As String = "Temp\" & Session.SessionID.ToString()
sTmpFolder = IO.Path.Combine(Request.PhysicalApplicationPath(), sTmpFolder)
file = IO.Path.Combine(sTmpFolder, file)
If IO.File.Exists(file) Then
IO.File.Delete(file)
End If
Catch ex As Exception
Response.StatusCode = 500
Response.StatusDescription = ex.Message()
End Try
xhr.responseText
como a resposta que estava à procura. Devolveu-me o texto no seguinte formato:
"{"error":true,"message":"The user name or password is incorrect"}"
O que não quero mostrar aos utilizadores. O que eu estava procurando é algo como abaixo:
alert(xhr.responseJSON.message);
xhr.responseJSON.message
dá-me a mensagem exacta do objecto Json que pode ser mostrada aos utilizadores.
$("#fmlogin").submit(function(){
$("#fmlogin").ajaxError(function(event,xhr,settings,error){
$("#loading").fadeOut('fast');
$("#showdata").fadeIn('slow');
$("#showdata").html('Error please, try again later or reload the Page. Reason: ' + xhr.status);
setTimeout(function() {$("#showdata").fadeOut({"opacity":"0"})} , 5500 + 1000); // delays 1 sec after the previous one
});
});
Se existir algum formulário é submetido com validate
Basta usar o resto do Código
$("#fmlogin").validate({...
...
...
});
Primeiro precisamos definir
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
**<serviceDebug includeExceptionDetailInFaults="true" />**
</behavior>
</serviceBehaviors>
Além disso, a nível do jquery, na parte de erro, é necessário analisar a resposta de erro que contém excepções como:
.error(function (response, q, t) {
var r = jQuery.parseJSON(response.responseText);
});
Depois, usando a mensagem R., poderá mostrar o texto de excepção.
Verificar código completo: http://www.codegateway.com/2012/04/jquery-ajax-handle-exception-thrown-by.html
Esta função basicamente gera uma API aleatória única e, no caso de não o fazer, então aparece uma janela com a mensagem de erro
Na Página De Visualização:
<div class="form-group required">
<label class="col-sm-2 control-label" for="input-storename"><?php echo $entry_storename; ?></label>
<div class="col-sm-6">
<input type="text" class="apivalue" id="api_text" readonly name="API" value="<?php echo strtoupper(substr(md5(rand().microtime()), 0, 12)); ?>" class="form-control" />
<button type="button" class="changeKey1" value="Refresh">Re-Generate</button>
</div>
</div>
<script>
$(document).ready(function(){
$('.changeKey1').click(function(){
debugger;
$.ajax({
url :"index.php?route=account/apiaccess/regenerate",
type :'POST',
dataType: "json",
async:false,
contentType: "application/json; charset=utf-8",
success: function(data){
var result = data.sync_id.toUpperCase();
if(result){
$('#api_text').val(result);
}
debugger;
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
}
});
});
});
</script>
Do Controlador:
public function regenerate(){
$json = array();
$api_key = substr(md5(rand(0,100).microtime()), 0, 12);
$json['sync_id'] = $api_key;
$json['message'] = 'Successfully API Generated';
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}
O parâmetro opcional callback especifica uma função de callback a executar quando o método load() estiver completo. A função de callback pode ter diferentes parâmetros:
Tipo: Função (jqXHR jqXHR, String textStatus, String errorThrown)
uma função a ser chamada se o pedido falhar. A função recebe três argumentos: o jqXHR (em jQuery 1.4.objecto x, XMLHttpRequest), uma cadeia de caracteres que descreve o tipo de erro que ocorreu e um objecto de excepção opcional, se ocorreu. Os valores possíveis para o segundo argumento (além de nulo) são "timeout", "error", "abort", e "parsererror". Quando um erro HTTP ocorre, errorThrown recebe a parte textual do estado HTTP, como "Not Found" ou "Erro Interno Do Servidor. A partir de jquery 1.5, a configuração de erro pode aceitar uma variedade de funções. Cada função será chamada por sua vez. Nota: este manipulador não é chamado para script cross-domain e pedidos JSONP cross-domain.