Internal server error 500 in backbone - javascript

while saving form details using backbone i m getting error as
POST http://localhost:8080/gamingengine/restful-services/badges 500 (Internal Server Error)
st.ajaxTransport.sendjquery.js:4
st.extend.ajaxjquery.js:4
Backbone.ajaxbackbone.js:1197
Backbone.syncbackbone.js:1178
_.extend.syncbackbone.js:284
_.extend.savebackbone.js:490
Backbone.Form.extend.saveBadgesbadges.js:219
st.event.dispatchjquery.js:3
st.event.add.y.handle
Uncaught SyntaxError: Unexpected token <
st.extend.parseJSONjquery.js:2
window.clearErrorscommon.js:386
st.event.dispatchjquery.js:3
st.event.add.y.handlejquery.js:3
st.event.triggerjquery.js:3
rjquery.js:4
st.ajaxTransport.send.r
my backbone code is as follows
this.model.save(this.getValue(), {
//beforeSend : setHeader, //added
iframe : true,
wait : true,
files : $file,
elem : this,
data : _.omit(this.getValue(), ['iconFile']),
silent : true,
success : function(model, response, options) {
alert("inside save..");
var error = false;
_.each(response, function(val, key) {
if (app.BadgesView.fields[key]
&& val instanceof Object
&& val.error) {
error = true;
app.BadgesView.fields[key]
.setError(val.message);
}
});
if (!error) {
app.BadgesView.model.set(model);
app.BadgesListCollection.add(model);
return;
}
return false;
},
error : function(model, response, options) {
console.log("error while save in badges.js : ");
}
});
and server side code is as follows which is using resteasy
#POST
#Consumes("multipart/form-data")
#Produces("text/html")
#Cache(noStore = true)
public final Response saveBadges(
#MultipartForm final BadgesForm badgesForm) throws IOException {
System.out.println("saveBadges called........");
final int no_of_coins = badgesForm.getNo_of_coins();
final String badge_name = badgesForm.getBadge_name();
final int score = badgesForm.getScore();
final int badge_id = badgesForm.getBadge_id();
final byte[] iconFile = badgesForm.getIconFile();
final Validator validatorNumeric = ValidationFactory
.getTextFieldNumericValidator();
validatorNumeric.validate("no_of_coins", no_of_coins,
threadlocalExceptions.get());
System.out.println("iconFile :" + iconFile);
if (iconFile.length >= GamingConstants.ONE) {
ValidationFactory.getImageContentValidator().validate("iconFile",
iconFile, threadlocalExceptions.get());
ValidationFactory.getImageSizeValidator().validate("iconFile",
iconFile, // added size // validator
threadlocalExceptions.get());
}
if (threadlocalExceptions.get().isEmpty()) {
try {
final Badges badges = new Badges();
badges.setNo_of_coins(no_of_coins);
badges.setBadge_name(badge_name);
badges.setScore(score);
badges.setBadge_id(badge_id);
final Coin coin = new Coin();
coin.setId(badgesForm.getCoin());
badges.setCoin(coin);
Badges.save(badges);
final Badges badgesObj = new Badges();
badgesObj.setBadge_id(badges.getBadge_id());
badgesObj.setCoin(coin);
badgesObj.setBadge_name(badges.getBadge_name());
badgesObj.setNo_of_coins(badges.getNo_of_coins());
badgesObj.setScore(badges.getScore());
if (iconFile.length >= GamingConstants.ONE) {
final String imgPath = "restful-services/badges/"
+ badges.getBadge_id() + "/image";
badgesObj.setIconPath(imgPath);
final String fileName = path + badges.getBadge_id()
+ ".png";
CommonUtils.writeIcon(iconFile, fileName);
} else {
badgesObj.setIconPath(defaultPath);
}
Badges.update(badgesForm.getBadge_id(), badgesObj);
final gamingengine.bind.Badges bindBadges = new gamingengine.bind.Badges();
bindBadges.setBadge_id(badgesObj.getBadge_id());
bindBadges.setCoin(badgesObj.getCoin());
bindBadges.setNo_of_coins(badgesObj.getNo_of_coins());
bindBadges.setBadge_name(badgesObj.getBadge_name());
bindBadges.setIconPath(badgesObj.getIconPath());
bindBadges.setScore(badgesObj.getScore());
final ObjectMapper mapper = new ObjectMapper();
final String jsonString = mapper.writeValueAsString(bindBadges);
return Response.ok().entity(jsonString).build();
} catch (DBException e) {
if (e.getMessage().startsWith(DBException.PARENT_NOT_EXISTS)) {
final String fieldName = e.getMessage()
.substring(e.getMessage().indexOf("-") + 1).trim()
.toLowerCase();
e.getValidationException()
.setMessage(
"The "
+ fieldName
+ " is already deleted.Please refresh the page ");
threadlocalExceptions.get().put(fieldName,
e.getValidationException());
}
}
}
final Map<String, ValidationException> exceptions = threadlocalExceptions.get();
threadlocalExceptions.remove();
final ObjectMapper mapper = new ObjectMapper();
final String exceptionJsonString = mapper
.writeValueAsString(exceptions);
return Response.ok().entity(exceptionJsonString).build();
}
while saving data of the form, backbone does not call the saveBadges() method of server side code
in chrome network it shows as
badges
/gamingengine/restful-services
POST
500
Internal Server Error
text/html
now i tried as
data:this.getvalue() in save() its sending all values to server except for iconPath
**iconPath : {
type : "FilePicker",
title : "Icon"
}**
and in save() of backbone
**var $file = $('input[name="iconPath"]', this.el);** this two lines are not sending iconPath, its empty any guesses
any help appreciated!!! thanks

The issue could be related to the content-type expected by your service, "multipart/form-data". Backbone by default does not provide an implementation to send a multipart request on the "save" method.
Here is a link with information about how you can send the multipart-request:
multipart form save as attributes in backbonejs
Also, message that you are receiving about the unexpected character ">" could be related to the "dataType" associated to the request, try to change it to "text" to avoid parsing to JSON, adding that you should be getting the correct error.
this.model.save(this.getValue(), {
//beforeSend : setHeader, //added
iframe : true,
wait : true,
files : $file,
dataType: "text",
elem : this,
data : _.omit(this.getValue(), ['iconFile']),
silent : true..
}
I will suggest to review your developer console as well in Chrome, Safari or Firefox to see how the request is been sent to the server, that could give you a better understanding how your request is been received by the server.
Also, try testing your service by external "Restful" tool, chrome provided the "Advance Restful Client" where you can test your service.
Hope this information helps to solve your issue or guide you in the right direction.

Related

Spring Web Application Returning 405 error on PUT Call

I have a Java Spring web application that creates a list of roles that can be assigned to users. However, I am having an issue creating new roles which is invoked through an AJAX PUT call that returns a 405 error. The application is running on Java 8 and Spring 5.1.1.
I have tried debugging both the front end and back end side. What I found was, the call successfully reaches the back-end, processes the call through and returns. However, the front-end will claim that an error occurred and returns a 405 error. But the issue is, the error does not provide any details on what is failing exactly. The most information I could find was this message:
TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
at Function.invokeGetter (<anonymous>:2:14)
at Object.error (http://localhost:8000/xxx/admin-user-search.html:1011:10)
at fire (http://localhost:8000/xxxx/webjars/jquery/3.1.1/jquery.js:3305:31)
at Object.fireWith [as rejectWith] (http://localhost:8000/xxxx/webjars/jquery/3.1.1/jquery.js:3435:7)
at done (http://localhost:8000/xxxx/webjars/jquery/3.1.1/jquery.js:9244:14)
at XMLHttpRequest.<anonymous> (http://localhost:8000/xxxx/webjars/jquery/3.1.1/jquery.js:9484:9)
Javascript:
function submitCreateNewRole(){
isBlank = false;
var myData;
newRoleName = $('#modalUserRoleSearchText').val();
newRoleDescription = $('#modelUserRoleDescText').val();
if (newRoleName=='' || newRoleDescription==''){
isBlank = true;
}
if (isBlank){
appAPI.setErrorBannerRole("Blank data is not allowed. Please enter non-blank data to create new Role.");
} else {
var UserRoleSearchModel = {};
var userRoleAction = "createNewUserRole" ;
RoleModel.ldapName = newRoleName;
RoleModel.roleDesc = newRoleDescription;
var token = $("meta[name='_csrf']").attr("content");
var URL = "json/admin-user-search?userRoleAction=" + userRoleAction + "&roleName=" + newRoleName + "&roleDesc=" + newRoleDescription;
var req = JSON.stringify(RoleModel);
var jqxhr = $.ajax({
type: "PUT",
url: URL,
headers: { "X-CSRF-TOKEN" : token },
data: req,
contentType: "application/json",
error: function (xhr, status, error) {
console.log("Failure caught");
console.log(xhr.responseText);
},
success: function(data){
myData = data;
}
}).done(function( msg ) {
$('#alertMessageSuccess').val('Successfully create new row');
}).fail(function(jqxhr) {
$('#alertMessageError').val('failed to create role' + newRoleName);
});
}
return myData;
}
Java Spring:
#RequestMapping(value = {
"admin-user-search"
}, method = RequestMethod.PUT)
public ModelAndView createNewUserRole(#AuthenticationPrincipal Principal principal,
#RequestParam(required = false) String pageCommand,
#ModelAttribute("UserModel") UserModel userSearch,
#ModelAttribute("RoleModel") RoleModel userRoleSearch,
#RequestParam(value = "roleName", required = false) String roleName,
#RequestParam(value = "roleDesc", required = false) String roleDesc,
#RequestParam(value = "userRoleAction", required = false) String userRoleCommmand, HttpServletRequest request) {
Results results = null;
List<Role> roleVOs = null;
String roleResponseMessage;
ModelAndView rView = new ModelAndView("admin-user-search");
if ("createNewUserRole".equals(userRoleCommmand)) {
userRoleSearch.clearAlertMessages();
userSearch.clearAlertMessage();
if ("".equals(roleName)) {
roleResponseMessage = "Unable to create a new role due to invalid or blank LDAP username enterred. Please try again with valid LDAP username.";
userRoleSearch.setErrorMessages(roleResponseMessage);
} else if ("".equals(roleDesc)) {
roleResponseMessage = "Unable to create a new role due to invalid or blank Role Description entered.";
userRoleSearch.setErrorMessages(roleResponseMessage);
} else {
try {
this.tdmcRoleDao.addNewRole(roleName, roleDesc);
roleResponseMessage = String.format("New user role '%s' has been added.", userRoleSearch.getLdapDn());
userRoleSearch.setSuccessMessages(roleResponseMessage);
userSearch.setSuccessMessages(roleResponseMessage);
roleVOs = retrieveAllRoles();
} catch (final SQLException e) {
LOGGER.error(e, TDMCMessages.TDMC_0142_DATABASE_INSERT_EXCEPTION, "tdmcRoleDao.addNewRole(newRoleLdap)");
roleResponseMessage = "Unable to create a new role -'%s' due to DB problem. Please retry with a new valid role name.";
userRoleSearch.setErrorMessages(roleResponseMessage);
userSearch.setErrorMessages(roleResponseMessage);
} catch (final DuplicateKeyException dupEx) {
roleResponseMessage = "Unable to create a duplicate role'. Please retry with non-duplicated role name.";
userRoleSearch.setErrorMessages(roleResponseMessage);
userSearch.setErrorMessages(roleResponseMessage);
}
if (roleVOs != null && !roleVOs.isEmpty()) {
results = populateRolesToResults(roleVOs);
}
userRoleSearch.setResults(results);
userRoleSearch.setSelected(roleVOs);
rView.addObject("RoleModel", userRoleSearch);
}
}
return rView;
}
When I run the application and try to create a new Role, I see that the PUT call reaches the Java server and successfully returns the view. However, on the Web client side, it throws the 405 error, and it's not clear what exactly is failing. Any insight would be very helpful.
On another note, the application also makes POST and GET calls as well, but those seem to work fine, so I cannot understand why the PUT calls are failing in this case.
EDIT: Fix code
first of all your url seems to be wrong, please check.
and change to post mapping, then post through body, something
like #requesrbody

Blueimp jQuery File Upload and my exception

I want to pass error message to Blueimp jQuery File Upload plugin. I use ASP.NET MVC and throw my own exception when some conditions are appeared (i.e. file is not real image, only image exception or image is too wide etc).
var file = Request.Files[i];
_service.ImageValidation(file.InputStream);
public void ImageValidation(System.IO.Stream fileStream)
{
Bitmap bmp = null;
try
{
bmp = new Bitmap(fileStream, false);
}
catch
{
throw new NoImageException();
}
if (bmp.Width > bmp.Height && (bmp.Width < 1024 || bmp.Height < 768))
throw new ImageDimensionTooSmall();
if ((bmp.Width <= bmp.Height) && (bmp.Width < 768 || bmp.Height < 1024))
throw new ImageDimensionTooSmall();
fileStream.Position = 0;
}
on client side I try to catch error by the following way:
$('#fileupload').fileupload({
url: '/SmartphonePhotographer/ManageFiles?ResponseID=' + ResponseID,
error: function (e, data) {
alert('error');
}
});
'data' variable always has 'error' value. 'e' has many properties, including statusText='Internal server error' and responseText (html page with exception). Question - how can I pass error message on server side to catch it on client side (maybe, there is an json format for errors, but I did not find it in documentation)
It goes to the error event because you are throwing an exception in your server side code. So the ajax call is getting a 500 internal error response.
What you can do is, instead of throwing an exception, return a json response with the error messages.
[HttpPost]
public ActionResult SaveImage()
{
if(IsFileNotValid()) //your method to validate the file
{
var customErrors = new List<string> {"File format is not good",
"File size is too bib"};
return Json(new { Status = "error", Errors = customErrors });
}
//Save/Process the image
return Json ( new { Status="success", Message="Uploaded successfully" });
}
And in the done() event, you can inspect the json response and show the error messages as needed.
$('#fileupload').fileupload({
url: '/SmartphonePhotographer/ManageFiles?ResponseID=' + ResponseID,
error: function (e, data,txt) {
alert('error' + txt);
}
}).done(function(response){
if(response.Status==="error")
{
$.each(services.Errors, function (a, b) {
alert(b);
});
}
});
With this approach, you can send multiple validation errors back to the client and client can process(show to user ?) it.
MVC 6
In MVC6, you can return an HttpStatusCode response directly from the MVC controller action. So no need to send a JSON response yourself.
[HttpPost]
public IActionResult SaveImage()
{
var customErrors = new List<string> { "File format is not good",
"File size is too bib" };
return HttpBadRequest(customErrors);
}
This will send a 400 Response to the caller with the data we passed(the list of errors) in the response. So you can access the responseJSON property of your error xHr object of the error event to get it
error: function (a, b, c) {
$.each(a.responseJSON, function (a, b) {
alert(b);
});
}
I agree your issue is that you are throwing an exception versus returning a controlled response. Most frameworks look for status codes in the 400x or 500x. So you want to return a friendly json object and a status code in those ranges. If you do that your data object in the error block will be what you returned.
MVC Land:
//get a reference to request and use the below.
return this.Request.CreateResponse(HttpStatusCode.BadRequest, "Your message here");
Web Api 2
Use an IHttpActionResult and return BadRequest("My error message"); If you do that it will set your status code and return the response as the data.

Can't connect to web service by JQuery

I use jquery (ajax) to connect to a web service which returns string , it is not working with me. it always go to error function. here is my web service :
[HttpGet]
[ActionName("GetImage")]
public string GetImage(string base64String, string imgName,string reqTitle , string reqSubject, string reqStatus,string Creator , DateTime creationdate )
{
try
{
using (PhMobAppEntities context = new PhMobAppEntities())
{
ClaimsApproval _ca = new ClaimsApproval();
_ca.imageBasestrg = base64String;
_ca.imageName = imgName;
_ca.Creator = Creator;
_ca.CreationTime = creationdate;
_ca.ReqStatus = reqStatus;
_ca.ReqTitle = reqTitle;
_ca.ReqSubject = reqSubject;
context.ClaimsApprovals.Add(_ca);
context.SaveChanges();
return "Success";
}
}
catch (DbEntityValidationException ex)
{
var errorMessages = ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
var fullErrorMessage = string.Join("; ", errorMessages);
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
}
and here is my js code :
$("#sendphoto").click(function () {
var url = "http://41.128.183.109:1212/api/Data/GetImage";
var data = {
imgName: "test"
};
$.ajax({
url: url,
type: 'Get',
data: data,
success: function (data) {
alert("Success");
},
error: function (data) {
alert("Please Check Your Internet Connection");
}
});
});
It is running ok when i tested my web service in advanced rest client ,please advice .
I tried connecting to your web service and I get the following response:
{"$id":"1","Message":"No HTTP resource was found that matches the request URI 'http://41.128.183.109:1212/api/Data/GetImage'."}
I think what you have is an internal problem with your c# code, probably with your routing. Your javascript call is probably working fine, but you are passing only one parameter, "test" while you have many more in your declaration.
What http response code are you getting?

Succesfull $.Ajax and $.Post calls always return failure from C#

I need a cross domain web api method to return valid jsonp to some javascript from C#. I can't seem to make this magic happen. I've looked around the web and can't find a start to end example that fits my needs and works... Fiddler shows that I'm returning valid json data but when I hit a breakpoint in F12 dev tools or firebug the result is a failure message.
Here is what I've currently got:
C#
/// <summary>
/// POST: /Instance/RefreshItem
/// </summary>
/// <param name="instanceId"></param>
/// <returns>Json</returns>
[HttpPost]
public System.Web.Mvc.JsonResult RefreshItem(int instanceId, Guid customerId)
{
try
{
var clientConnection = Manager.ValidateInstance(customerId, instanceId);
clientConnection.RefreshItem();
var result = new MethodResult()
{
Success = true,
Value = instanceId,
Message = "Item successfully refreshed."
};
return new System.Web.Mvc.JsonResult() { Data = result };
}
catch (Exception ex)
{
Manager.LogException(_logger, ex, customerId, instanceId);
var result = new MethodResult()
{
Success = false,
Value = instanceId,
Message = ex.GetBaseException().Message
};
return new System.Web.Mvc.JsonResult() { Data = result };
}
}
JS
Example.RefreshItem = function ()
{
Example.SDK.JQuery.getSettings(
function (settings, userId, userLocaleId)
{
alert("Attempting to refresh item for instance " + settings.ConnectionId + "\r\nThis may take awhile.");
var url = settings.SystemUrl + "/Api/WebApiServices/ExampleAdmin/RefreshItem?customerId=" + settings.CustomerId + "&instanceId=" + settings.ConnectionId;
$.ajax({
url: url,
dataType: "jsonp",
jsonpCallback: 'RefreshItemCallback',
success: RefreshItemCallback
})
},
Example.SDK.JQuery.defaultErrorCallback
);
}
function RefreshItemCallback(data)
{
alert(data.d.Message);
}
I've also tried $.Post().Always() with the same results.
What am I doing wrong???
I think your problem is that you're instantiating a JsonResult instead of using the Json method.
Presumably the C# method you have is in a controller, so instead of
return new System.Web.Mvc.JsonResult() { Data = result };
do:
return Json(result);
This method probably sets some of the other properties of the JsonResult that, when not set, will not be properly received by the client.
See how Microsoft only shows you how to create a JsonResult via the Json method on MSDN
Note that the same is probably true with methods like View, Content, and File.
Fight all week unable to find an answer until you ask the question somewhere... Within 30 minutes of asking I found this: http://bob.ippoli.to/archives/2005/12/05/remote-json-jsonp/ which was exactly what I needed.
Thanks to all who posted.

Converting byte array to jpeg image in javascript

I have an asp.net page.
Inside this page I have an img control/element.
I am calling an ashx page on my server.
This ashx page accepts a timestamp from the client and compares it to a timestamp stored on the server.
If the timestamps do not match then I return an image which has been converted to a byte array (in C#).
If the timestamps do not match then I return a string value of "-1".
So, this is a cut-down of my ashx page:
public void ProcessRequest (HttpContext context) {
context.Response.AddHeader("Access-Control-Allow-Origin", "*");
try
{
string clientTS = context.Request.QueryString["clientTS"];
if (clientTS == serverTS)
{
//new version available. refresh browser
context.Response.ContentType = "text/json";
string value = "-1";
context.Response.Write(value);
}
else
{
context.Response.ContentType = "image/jpg";
byte[] data = Shared.GetMobileNextFrame("par1", 0);
context.Response.BinaryWrite(data);
}
}
catch (Exception ex)
{
context.Response.ContentType = "text/json";
context.Response.Write("ERR");
}
}
And in my javascript code:
function GetImageStatus() {
finished = false;
var val = url + '/Mobile/isNewFrame.ashx?Alias=' + Alias + '&CamIndex=' + camIndex + '&Version=' + version + '&GuidLogOn=' + guidLogOn;
$.ajax({
url: val,
type: 'GET',
timeout: refreshWaitlimit,
data: lastTS,
success: function (response, status, xhr) {
var ct = xhr.getResponseHeader("content-type");
if (ct.indexOf('json') > -1) {
//no update
}
else {
try {
live1x4.src = 'data:image/bmp;base64,' + encode(response);
}
catch (err) {
alert(err);
}
}
},
error: function (jqXHR, textStatus, errorThrown) {
//handle error
}
});
}
function encode(data) {
var str = String.fromCharCode.apply(null, data);
return btoa(str).replace(/.{76}(?=.)/g, '$&\n');
}
But I get an error returned:
TypeError: Function.prototype.apply: Arguments list has wrong type
If I just apply:
live1x4.src = 'data:image/bmp;base64,' + btoa(response);
instead of:
live1x4.src = 'data:image/bmp;base64,' + encode(response);
I get this error:
InvalidCharacterError: btoa failed. the string to be encoded contains
characters outside of the Latin1 range.
I have tried using a canvas control with example code i have found on this site. I do not get an error but I also do not get an image.
I know the image is valid because my old code was point the image.src directly to the ashx handler (and i was not comparing timestamps).
I do not want to encode the byte array to base64 string on the server because that would inflate the download data.
I was wondering if I was using the wrong context.Response.ContentType but I could not see what else I could use.
What am i doing wrong?
When looking at the documentation at MDN you should pass 1 or more parameters to fromCharCode. You pass none in this line:
var str = String.fromCharCode.apply(null, data);
The syntax is:
String.fromCharCode(num1, ..., numN)
There is although the apply method as your said in comments, but you use it the wrong way. The first parameter shouldn't be null.
The syntax of that is (from Convert array of byte values to base64 encoded string and break long lines, Javascript (code golf)):
somefunction.apply(thisObj[, argsArray])
Just use
var str = String.fromCharCode.apply(data);
So use the thisObj parameter to pass the data.

Categories