I have to give user a proper message while ajax call got fail
My Ajax call is as follows:
$http({
method:'PUT',
url:"/myapp/web/update",
crossDomain:true,
data:dataobj,
headers:{
'Content-Type':'application/json',
}
}).success(function (data) {
console.log("error"+JSON.stringify(data));
}).error(function (data, status, headers, config) {
console.log("error"+JSON.stringify(data));
});
from the backed i have used Spring MVC 4 as restfull api. From that i am validating the data and send response accordingly. If something went wrong in validation i throw custom exceptions.
Now if i throw just exception it got cached in Ajax success function but i want it to have to catch this in error function. for this i add following line of code :
response.sendError(500);
Now it got cached in error function as expected but i cant find JSON error message with it. Can anybody tell where i went wrong in the code.
Edit:
Following is the Code where i am responding with error message
#ControllerAdvice
public class ExceptionHandlingController{
#ExceptionHandler(EmployeeNotFoundException.class)
public #ResponseBody ExceptionJSONInfo handleEmployeeNotFoundException(HttpServletRequest request, Exception ex){
ExceptionJSONInfo response = new ExceptionJSONInfo();
response.setUrl(request.getRequestURL().toString());
response.setMessage(ex.getMessage());
response.sendError(500);
return response;
}
}
Related
I'm currently building a single page application based on Laravel and VueJS.
Is there any better way then mine to handle errors with axios?
This is how I currently do it when a user clicks on login button:
VueTemplae:
methods : {
authenticateUser() {
axios.post('/api/login', this.form).then(() => {
this.$router.push({name : 'home'});
}).catch((error) => {
this.error = error.response.data.message;
});
}
}
Api route:
public function login() {
try {
// do validation
} catch(Exception) {
// validation failed
throw new Exception('login.failed');
}
// manually authentication
if(Auth::attempt(request()->only('email', 'password'))) {
return response()->json(Auth::user(), 200);
}
// something else went wrong
throw new Exception('login.failed');
}
Unfortunately, throwing an exception always prints an internal server error into the console.
If I return something else than an exception, axios always executes then().
Is there any way to prevent this or a better way to handle axios responses?
Thank you!
Your API needs to return a response with a 4XX status code in order for the catch block to fire in your Vue component.
Example:
After you catch the error on the API side, send a response with status code 400 Bad Request. It will be formatted similarly to your successful login response, but with an error message and 400 status code instead of 200.
Maybe this is silly question but I'm trying to learn Spring MVC and I have everything working except for the exceptions. So I have a simple form application where the user can register, if the user already exists I'd like to send an error code to the UI so that it knows why it failed. Heres my code:
#ResponseBody
#PostMapping("users")
public ResponseEntity addUser(#RequestBody User user) {
List<User> users = usersService.addUser(user);
if(users == null) return new ResponseEntity(HttpStatus.EXPECTATION_FAILED);
else return new ResponseEntity<>(users, HttpStatus.ACCEPTED);
}
It works fine, as in it returns a status code to the UI but the exception returns it in this string format:
Error: Request failed with status code 417
at createError (createError.js:17)
at settle (settle.js:19)
at XMLHttpRequest.handleLoad (xhr.js:69)
The log above is from a console log from the UI, right after the catch below:
function register(user) {
return dispatch => {
axios.post(`${BASE_URL}/users`, user).then((response) => {
console.log(response);
dispatch(resetError());
dispatch(success(user));
}).catch((e) => {
console.log('e', e);
dispatch(error(e.status));
})
};
function success(user) { return { type: userConstants.REGISTER, payload: user } };
};
Funny enough it actually prints exactly what I'm looking for if the http call succeeds. Here's what it prints on the happy path of the promise (ACCEPTED):
Notice that it has a status property. I'd very much not like to parse a string on the UI side just to get the error code from the service. Why is the response object different? The only thing I've changed is the status code. How can I make the error status give the UI a nice object instead of a string?
If you'd like to pull the branch here is the URL: https://github.com/MatTaNg/react-form
The code snippets are in the UsersResource file
Instead of console.log('e', e) try console.log('e', e.response.status).
Source:
https://github.com/axios/axios#handling-errors
I am displaying a table of data using datatables 1.10.12. The user can specify input parameters that cause an error on the server. An appropriate error message should be displayed to the user so they can modify their setup, however the only error options seem to be:
SHow the following generic error in an alert: "DataTables warning: table id=trackingTable - Ajax error. For more information about this error, please see http://datatables.net/tn/7"
Show the generic error in the browser console
Modify the server to return no rows, that is fail silently.
Does anyone know how to show a custom error after a datatables ajax request fails?
The following code sample is taken from the datatables documentation. Datatables handles the ajax call and handles success and error.
$(document).ready(function() {
$('#example').DataTable( {
"ajax": '../ajax/data/arrays.txt'
} );
} );
A 4th option I could add to the list would be to modify the datatables source code to handle the an error response myself. Which I'm not that keen on.
This question was asked in 2015 however it did not get an answer. See:
display server side exception
If you pass an object to the ajax property you can override the jQuery.ajax() error method:
$(document).ready(function () {
$('#example').DataTable({
ajax: {
url: '../ajax/data/arrays.txt',
error: function (jqXHR, textStatus, errorThrown) {
// Do something here
}
}
});
});
https://datatables.net/reference/option/ajax#object
This will stop the standard error message in the alert box.
Please note, it is not recommended to override the success method of jQuery.ajax() as it is used by DataTables.
You can implement your own custom error message globally like the example below.
$(document).ready(function() {
$.fn.dataTable.ext.errMode = () => alert('Error while loading the table data. Please refresh');
$('#example').DataTable( {
"ajax": '../ajax/data/arrays.txt'
});
});
Answering just in case someone is still looking for a solution.
In my case, I did the following
At server side set DataTablesOutput object.setError("ErrorMsg")
In my js method $.fn.dataTable.ext.errMode = 'none'; to avoid the error popup.
Created an error div in my page to display the custom error message
Added the below to my js method to handle error
$('#myDataTable')
.on('error.dt',
function(e, settings, techNote, message) {//Logic to set the div innertext
}
try {
$.ajax({
-------
-------
success: function (data){
//ShowDataTable is a js Function which takes ajax response data and display it.
ShowDataTable(data);
},
//this error will catch server-side error if request fails
error: function (xhr, textStatus, errorThrown) {
alert(errorThrown);
ShowDataTable(null);
}
})
}
//this catch block will catch javascript exceptions,
catch (Error) {
if (typeof console != "undefined") {
console.log(Error);
ShowDataTable(null);
alert(Error);
}
}
EDIT
If you are willing to accept the error (for example if you cannot alter the backend system to fix the error), but don't want your end users to see the alert() message, you can change DataTables' error reporting mechanism to throw a Javascript error to the browser's console, rather than alerting it. This can be done using:
$.fn.dataTable.ext.errMode = 'throw';
I have a backbone model. I add the following attributes to the model
model.set('x',x);
model.set('y',y);
model.set('z',z);
and than i call model.save....
In the backend what i do is i set some more properties to brandDTO
But what i see is that the error attribute is not there in the error callback model
app.Model.BrandModel = Backbone.Model.extend({
url : '/brand/cu'
});
var brand = new app.Model.BrandModel();
brand.save(null, {
success : function(model, response) {
},
error : function(model, response) {
}
});
#RequestMapping(value = "/brand/cu", method = RequestMethod.POST, produces = "application/json")
#ResponseBody
public BrandDTO createBrand(#RequestBody BrandDTO brandDTO,
HttpServletResponse response) {
brandDTO.setErro("error", error)
This error field is not there in the error callback model..
I am not sure if i am thinking right....
You are thinking right, just need to arrange this both on client and server.
I see you are using Java, is this SpringMvc?
First, you should serialize your response:
On server:
1.)Create an object/class called SerializedResponse which has "data", "success", "exception" properties.
2.)Then you can wrap a try{}catch{} on the create brand business logic, and if it succeeded set the "success" to true, if it failed to "false", if theres an exception, put it in the exception object.
Note that even if you have an error in your logic, you will always get success, as long as the operation was performed and you have recieved a response, and unless the http status code is not 200, this is handled by the jqXhr object so you can handle the callbacks from there, meaning:
success : function(model, response) {
var data = JSON.parse(response);
if(data.success){
//ALL OK
}
else {
//Fail
}
},
error: function(){
//Error
}
I successfully implemented client editors and a server side API.
Now I'm adding more validation at the server side, and besides returning the proper HTTP code (200 for OK, 4xx for other uses, 500 for errors, etc.) I want to return a list of validations that failed after the submission generated by Model.save().
I run it this way:
myModel.save({
success: function (a, operation, c) {...},
failure: function (a, operation, c) {...}
});
But if there was a failure, the operation object only have the response status and its statusText, all through
operation.error.status // i.e. 409
operation.error.statusText // "Conflict"
But server side a detail of the failing validations (mostly domain level ones) are being added to the response.
Is there a way I can get what the server sent as the body of the HTTP response to the PUT/POST submission?
Do I have to return it using a particular JSON structure?
EDIT:
I'm now returning this as the body of the HTTP Response (with code 4xx):
{
data: {/* the record serialized */},
success: false, // or true if everything went ok
message: "This failed because X and Y."
}
Thanks in advance.
For some reason Ext is not attaching the response content to the error object, but it triggers an exception event if there is a failure.
So what we did was to handle the "exception" event of the model's proxy, and then we will have access to the XHR response, being able to do whatever we want with it.
myModel.getProxy().on('exception', this.onProxyException, this);
The handler is as follows:
onProxyException : function (proxy, response, operation) {
var errors;
errors = Ext.JSON.decode(response.responseText).message;
/* Whatever is needed with the errors */
}
In this example we asume the errors come in JSON format, they could be a simple text string, which wouldn't require the use of decode().
According to this blog:
http://code.tonytuan.org/2013/07/extjs-get-server-response-in-modelsave.html
You can write code like this:
model.save({
success: function (record, operation) {
// json response from server
console.log(operation.response);
},
failure: function (record, operation) {
// undefined
console.log(operation.response);
// json response from server
console.log(operation.request.scope.reader.jsonData);
}
});
in reader block add: messageProperty: 'message'
from server return: success:false, message: 'error test'
from failure get error:
failure: function (records, operation) {
Ext.Msg.alert('error', operation.error);
}