Getting 500 error on some docs but not others. Why? - ajax

My add-in for MS Word works for some docs but not others. For test-doc-A, it works fine. I get the results I want. test-doc-B throws a 500 error on the $.ajax call that sends the text to the server. Both docs are one page. Granted, 500 errors are supposed to be "server" side. But what could be so different between these docs that's causing this?
The server logs don't indicate anything (to my eye) that tells me what the issue is.
test-doc-A (All Good)
2019-02-28 23:41:33 MyApiEndPoint POST /api/Document/Upload X-ARR-LOG-ID=8b253a46-bca8-4981-9ded-3fdf671fe63c 443 - myIpAddressMozilla/5.0+(Windows+NT+10.0;+WOW64;+Trident/7.0;+Touch;+rv:11.0)+like+Gecko - https://localhost:44399/Home.html?_host_Info=Word$Win32$16.01$en-US myServerUrl 200 0 0 664 3793 46
test-doc-B (500 Error)
2019-02-28 23:42:13 MyApiEndPoint POST /api/Document/Upload X-ARR-LOG-ID=b0095aa0-9fc5-4a26-83b0-40d44ff160ba 443 - myIpAddress Mozilla/5.0+(Windows+NT+10.0;+WOW64;+Trident/7.0;+Touch;+rv:11.0)+like+Gecko - https://localhost:44399/Home.html?_host_Info=Word$Win32$16.01$en-US myServerUrl 500 0 0 326 11306 46
Is there some way to compare the text that's being sent? Am I using the right method 'range.load("text")'?
The only difference between the docs appears to be formatting. But, I'm just sending the text, regardless of formatting, aren't I?
Do I need to "clean" the text before sending? Just so confused, right now.
function sendTextToServer() {
Word.run(function (context) {
var doc = context.document;
var range = doc.body;
range.load("text");
return context.sync()
.then(function () {
var myData = '{\"FileName\": \"WordAddIn-Test\",\"Text\": \"' + range.text + '\" }';
// begin promise
var promise = $.ajax({
url: urlToUse + "/Upload",
method: 'POST',
contentType: 'application/json; charset=utf-8',
beforeSend: function (request) {
request.setRequestHeader("Authorization", "Negotiate");
},
crossDomain: true,
dataType: 'json',
processData: false,
cache: false,
data: myData,
success: function (data) {
log("sendTextToServer Success: " + JSON.stringify(data));
},
error: function (xhr, textStatus, errorMessage) {
log("sendTextToServer promise Error: " + errorMessage + " : " + JSON.stringify(xhr) + " : " + textStatus);
}
});
// end promise
// do something with promise
promise.done(function (data) {
myDocID = data.documentID;
log("sendTextToServer myDocID: " + myDocID);
log("url = " + urlToUse + "/Status?documentID=" + myDocID);
setTimeout(function () { goDoSomethingElse(); }, 2000);
});
})
.then(context.sync);
}).catch(function (error) {
log("Error: " + error);
if (error instanceof OfficeExtension.Error) {
log("Debug info: " + JSON.stringify(error.debugInfo));
log("Something went wrong. Trying again");
}
});
}
"Looks like I picked the wrong week to quit sniffing glue."
~Steve McCroskey

Related

Ajax post call seems to work, still throws error?

Although the code works as expected it throws
"An error occurred whilst trying to contact the server: 200 parsererror SyntaxError: Unexpected end of JSON input"
The success branch is never called but the data arrives to the api.
Should I be concerned and solve it or it probably won't cause problems elswhere? Thank you for your help.
<script>
$(document).ready(function () {
$("#Save").click(function () {
var data2send = JSON.stringify("test");
$.ajax({
url: 'https://localhost:44348/api/products/PostProduct',
type: 'POST',
data: data2send,
contentType: 'application/json',
dataType: 'json',
success: function (data2send) {
console.log(data2send);
},
error: function (jQXHR, textStatus, errorThrown) {
console.log("An error occurred whilst trying to contact the server: " + jQXHR.status + " " + textStatus + " " + errorThrown);
console.log(data2send);
}
});
});
});
</script>
Controller
[HttpPost]
[Route("PostProduct")]
public void Post([FromBody] string obj)
{
Product.prod.Add(new Product() { ProductId = 12, ProductName = obj, Price = 12 });
}

Posting a pdf to Solr using Ajax

I am trying to push (Post) pdf files to Solr/Tika for text extraction and indexing using Ajax/js. I've gotten the following curl command to work:
curl 'http://localhost:8983/solr/techproducts/update/extract?literal.id=doc1&commit=true' -F "myfile=#/PathToFile/SomeDoc.pdf"
This command puts the desired pdf into the Solr Index, and I can retrieve it just fine. However, I need to be able to do this from a web browsers. After much googling, and a little experimentation I've got the following js code ALMOST working. It returns a 0 status code, and status of Success, but nothing gets committed to the index:
$("#solrPost").click(function(event) {
event.stopPropagation();
event.preventDefault();
/* Read a local pdf file as a blob */
let fileAsBlob = null;
let file = $('#upload_file')[0].files[0];
let myReader = new FileReader();
myReader.onloadend = function() {
fileAsBlob = myReader.result;
sendToSolr(fileAsBlob);
};
fileAsBlob = myReader.readAsArrayBuffer(file);
function sendToSolr(fileAsBlob) {
$.ajax({
url:"http://localhost:8983/solr/techproducts/update/extract?literal.id=doc2&commit=true",
type: 'POST',
data: fileAsBlob,
cache: false,
crossOrigin: true,
dataType: 'jsonp',
jsonp: 'json.wrf',
processData: false,
contentType: false,
success: function(data, status) {
console.log("Ajax.post successful, status: " + data.responseHeader.status + "\t status text: " + status);
console.log("debug");
},
error: function(data, status) {
console.log("Ajax.post error, status: " + data.status + "\t status text:" + data.statusText);
},
done: function(data, status) {
console.log("Ajax.post Done");
}
});
}
This is SO close to working, but I just can't figure out what's going wrong. All indications (From client side) are good, but nothing added to the index.
Note:
The fileReader is working, I see an Array of the same size as the source pdf.
Even though I specify POST, when I examine the network tab in the browser/debugger, it says GET.
I've hardcoded the literal.id=doc2 for simplicity, not a long term strategy...
I know there are similar posts, but none address the issue of extracting pdf's using Solr/Tika outside of the provided post script. Thanks in advance.
Well it took some searching but thanks to a post by "tonejac" I found the solution.
If you look at: [JQuery Ajax is sending GET instead of POST
The VERY last comment states that if you use dataType:jsonp that "POST" gets converted to "GET". I deleted the jsonp, installed a plugin to handle the CORS issue I was trying to avoid by using jsonp, and viola, it worked. For those interested, the working code is posted below. It's not fancy or robust but allows me to post or get documents (.pdf, .docx...) to Solr from a web app. I've only posted the js code, but the html is simple and provides an input of type "file", as well as inputs to set id for posting docs, or searching by id. There are two buttons, solrPost, and solrGet which call the listeners in the js. The connectSolr() function is called from the html onLoad.
function connectSolr() {
$("#solrPost").click(function(event) {
event.stopPropagation();
event.preventDefault();
/* Read a local pdf file as a blob */
let fileAsBlob = null;
let file = $('#upload_file')[0].files[0];
let myReader = new FileReader();
myReader.onloadend = function() {
fileAsBlob = myReader.result;
sendToSolr(fileAsBlob);
};
fileAsBlob = myReader.readAsArrayBuffer(file);
/* Get the unique Id for the doc and append to the extract url*/
let docId = $("#userSetId").val();
let extractUrl = "http://localhost:8983/solr/techproducts/update/extract/?commit=true&literal.id=" + docId;
/* Ajax call to Solr/Tika to extract text from pdf and index it */
function sendToSolr(fileAsBlob) {
$.ajax({
url: extractUrl,
type: 'POST',
data: fileAsBlob,
cache: false,
jsonp: 'json.wrf',
processData: false,
contentType: false,
echoParams: "all",
success: function(data, status) {
console.log("Ajax.post successful, status: " + data.responseHeader.status + "\t status text: " + status);
console.log("debug");
},
error: function(data, status) {
console.log("Ajax.post error, status: " + data.status + "\t status text:" + data.statusText);
},
done: function(data, status) {
console.log("Ajax.post Done");
},
});
}
});
$("#solrGet").click(function(event) {
event.stopPropagation();
event.preventDefault();
let docId = "id:" + $("#docId").val();
$.ajax({
url:"http://localhost:8983/solr/techproducts/select/",
type: "get",
dataType: "jsonp",
data: {
q: docId
//wt: "json",
//indent: "true"
},
jsonp: "json.wrf",
//"json.wrf": "?",
success: function(data, status) {
renderDoc(data, status);
},
error: function(data, status) {
console.log("Ajax.get error, Error: " + status);
},
done: function(data, status) {
console.log("Ajax.get Done");
}
});
console.log("Debug");
});
let renderDoc = function(theText, statusCode) {
let extractedText = theText.response.docs[0].content[0];
let extractedLinks = theText.response.docs[0].links;
let $textArea = $("#textArea");
$textArea.empty();
let sents = extractedText.split('\n')
sents.map(function(element, i) {
let newSpan = $("<span />");
$textArea.append(newSpan.html(element).append("<br/>"));
});
console.log("debug");
};
}

Ajax request fails in Cordova application Visual studio

I am Using visual studio 2015 to build android application using cordova. It works fine in the emulator. but when i am releasing it ajax request is failing where as same thing works on emulator.no error is seen in log but only the ajax error.
var url = 'http://oployeelabs.net/demo/demo_doctorola/doctorola-server/index.php/doctor_panel_api/validation_modified/format/json';
load();
$.ajax({
url: url,
data: { cell_no: phone, pass: pass },
method: 'POST',
dataType: 'json',
success: function (data) {
alert();
if (data == "false")
{
alert("Wrong password");
}
else
{
localStorage.doctorid = data[0].id;
localStorage.userinfo = JSON.stringify(data);
$.ajax({
url: "http://oployeelabs.net/demo/demo_doctorola/doctorola-server/index.php/api/information/meta-info/location/id/"+data[0].id+"/username/9791a47fef07649b1c3e70749e898153/password/2d593e25d0560b19fd84704f0bd24049/format/json",
method: 'GET',
dataType: 'json',
success: function (dt) {
localStorage.Chamberinfo = JSON.stringify(dt);
mainView.router.loadPage({ url: 'menu.html', ignoreCache: true, reload: true })
$('.toolbar').removeClass('hide');
}
});
}
//if (data === "ok") {
// $(".confirm_appointment").remove();
// var anc = "<a id='confirm_appointment' class='confirm_appointment' style='opacity: 0;' href='confirm.html' data-context='{\"slot_id\": \"" + slot_id + "\",\"slot_date\": \"" + slot_date + "\", \"email\": \"contact#john.doe\"}'>profile</a>";
// $(document).find('.page_content').append(anc);
// $(".confirm_appointment")[0].click();
//}
//else {
// myApp.hidePreloader();
// myApp.alert("", "Sorry, this slot has been booked. Please try with another slot.");
//}
},
error: function (xhr, status, exception) {
alert(xhr.responseText+" "+status+" "+ exception);
console.log("Error: " + xhr.responseText + " - " + exception);
},
complete: function () {
myApp.hidePreloader();
unload();
}
});
Strangely it worked after i uninstalled whitelist plugin and installed it again. i dont know why but i think its a bug of cordova.

Force.com : Rest API Bad Request in Query Like

I got 'bad request" message on the below Rest API Ajax call, When I tested on Developer console it return data successfully.
var _url = auth.get("instance_url") +
"/services/data/v28.0/query/?q=SELECT Id, Name FROM Account WHERE Website LIKE '%gmail.com%' ";
$.ajax({
url: _url,
cache: false,
async: false,
type: 'GET',
contentType: 'application/json',
headers: {
'Authorization': 'OAuth ' + auth.getAccessToken()
},
success: function (data) {
console.log("accounts: " + JSON.stringify(data));
result = data;
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus + +errorThrown);
}
});
You need to URLEncode the query parameter, spaces are not valid in a query string, e.g.
var _url = auth.get("instance_url") + "/services/data/v28.0/query?q=" + encodeURIComponent("select id,name from account");

detect a 407 error and persist for all subsequent requests

I have a simple javascript that uses $.ajax() from JQuery which works great for GET/POST. However, for some users that are behind a proxy, they receive the 407 error as outlined in the post below.
407 Proxy Authentication Required
Now, as you will see, I've updated that post stating that the usage of JSONP will suffice as a workaround. Where I'm at now, is I don't want to use JSONP all the time, only when it is required.
function original() {
$.ajax({
url: "http://somecool.url/foo",
data: { id:"bar"},
statusCode: {
407: foo()
},
success: function(data) {
$.each(data, function(k,v) {
$('#foo').append("<li>" + k + ":" + v + "</li>");
});
}
});
}
function foo() {
$.ajax({
url: "http://somecool.url/foo",
data: { id:"bar" },
dataType: "jsonp",
success: function(data) {
$.each(data, function(k,v) {
$('#foo').append("<li>" + k + ":" + v + "</li>");
});
}
});
}
$(document).ready(function() {
original();
});
Is it possible to persist the status of the first failure, which returns the 407 error when there is a proxy issue so that all subsequent requests do not go to the original() function and go to the foo() function?
My original answer (below) was dealing with function name override to accommodate the code in your question. However, there's a better solution, since after all you only want to switch all requests to JSONP if and only if you receive a 407 response code.
$.ajaxSetup() was designed to do exactly that:
function original() {
$.ajax({
url: "http://somecool.url/foo",
data: { id:"bar"},
statusCode: {
407: function() {
$.ajaxSetup({ dataType: "jsonp" });
// Now all AJAX requests use JSONP, retry.
original();
}
},
success: function(data) {
$.each(data, function(k,v) {
$('#foo').append("<li>" + k + ":" + v + "</li>");
});
}
});
}
With this strategy, once 407 is received, all the future AJAX requests will use JSONP.
For the sake of history, here is my original answer.
You can permanently change the function stored in original when you receive a 407 response code for the first time:
function original() {
$.ajax({
url: "http://somecool.url/foo",
data: { id:"bar"},
statusCode: {
407: function() {
window.original = foo;
foo();
}
},
success: function(data) {
$.each(data, function(k,v) {
$('#foo').append("<li>" + k + ":" + v + "</li>");
});
}
});
}
From then on, the name original will refer to foo(). You can even change the function and call its replacement at the same time:
407: function() {
(window.original = foo)();
}

Resources