since a couple of hours ago all my parse functions have been returning invalid json. Nothing to do with the cloud code... I even tried rolling it back. I'm on the android platform and haven't made any game breaking changes to it..
For example,
I have a login function...
Parse.Cloud.define("loginuser", function(request, response){
var useremail = request.params.useremail;
var userpassword = request.params.userpassword;
var usersource = request.params.usersource;
Parse.User.logIn(useremail, userpassword,{
success:function(user){
// Sets either candidate or business to be true depending on condition
if (usersource == "candidate"){
user.set("candidate", true);
} else if (usersource == "business"){
user.set("business", true);
}
user.save(null, {
// login success & return
success: function(user){
response.success(user);
}, error: function(error){
response.error(error);
}
});
},
error:function(user, error){
// login failure
response.error(user, error);
}
});
});
With no change to it... it suddenly starts throwing error:
01-05 22:37:30.175 1052-1052/recruitr.recruitr E/Login error: com.parse.ParseRequest$ParseRequestException: bad json response
01-05 22:37:46.045 1052-1052/recruitr.recruitr E/Signup Error: com.parse.ParseRequest$ParseRequestException: bad json response
Does anyone know why?
EDIT:
Ran debugger and it pops this out when the error message shows up:
this = {LoginActivity$4#4619}
cancel = {boolean[1]#4623}
logincredentials = {HashMap#4624} size = 3
parseUser = null
e = {ParseRequest$ParseRequestException#4625} "com.parse.ParseRequest$ParseRequestException: bad json response"
isPermanentFailure = false
code = 100
cause = {JSONException#4630} "org.json.JSONException: Value <html> of type java.lang.String cannot be converted to JSONObject"
cause = {JSONException#4630} "org.json.JSONException: Value <html> of type java.lang.String cannot be converted to JSONObject"
detailMessage = {String#4638} "Value <html> of type java.lang.String cannot be converted to JSONObject"
stackState = {long[34]#4639}
stackTrace = {StackTraceElement[0]#4633}
suppressedExceptions = {Collections$EmptyList#4634} size = 0
shadow$_klass_ = {Class#497} "class org.json.JSONException"
shadow$_monitor_ = -1960135782
detailMessage = {String#4631} "bad json response"
stackState = {long[30]#4632}
stackTrace = {StackTraceElement[0]#4633}
suppressedExceptions = {Collections$EmptyList#4634} size = 0
shadow$_klass_ = {Class#4592} "class com.parse.ParseRequest$ParseRequestException"
shadow$_monitor_ = -2123277170
Found the problem:
The Android Parse SDK was having problems with a new update. Parse was not actually initializing in the code at all (keys weren't working/initialization was not working)
Fix the error by changing the dependency:
compile 'com.parse:parse-android:1.+'
to
compile 'com.parse:parse-android:1.12.0'
or
compile 'com.parse:parse-android:1.10.0'
Both seem to work flawlessly as of this moment in time.
Related
I', trying to do a emscripten_fetch() and always get a return value of 0. Not sure what is going on, I switched to a javascript version, which works but has it's own problems.
C++ - can anyone see what I'm doing wrong here? To me, it looks like the header data isn't getting set properly, as I get this error:
Uncaught TypeError: XMLHttpRequest.open: Cannot convert argument 1 to ByteString because the character at index 2 has value 56770 which is greater than 255.
Here is the code:
emscripten_fetch_attr_t attr;
emscripten_fetch_attr_init(&attr);
strcpy(attr.requestMethod, "POST");
attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_WAITABLE;
const char *headers[] = {"Content-Type", "application/json", 0};
attr.requestHeaders = headers;
attr.requestData = request.c_str() ;
attr.requestDataSize = request.length() ;
qDebug("making fetch with URL: %s data: %s", req.c_str(), attr.requestData) ;
emscripten_fetch_t *fetch = emscripten_fetch(&attr, "http://172.23.4.90/jsonrpc"); // Blocks here until the operation is complete.
EMSCRIPTEN_RESULT ret = EMSCRIPTEN_RESULT_TIMED_OUT;
while(ret == EMSCRIPTEN_RESULT_TIMED_OUT)
{
// possibly do some other work;
ret = emscripten_fetch_wait(fetch, 5000) ; // milliseconds to wait, 0 to just poll, INFINITY=wait until completion
}
if (fetch->status == 200) {
qDebug("Finished downloading %llu bytes from URL %s.", fetch->numBytes, fetch->url);
// The data is now available at fetch->data[0] through fetch->data[fetch->numBytes-1];
retval.append(fetch->data, fetch->numBytes) ;
} else {
qDebug("Downloading %s failed, HTTP failure status code: %d.", fetch->url, fetch->status);
// throw jsonrpccxx::JsonRpcException(-32003, "client connector error, received status != 200");
}
emscripten_fetch_close(fetch);
I've tried with the wait, and a full sync with the same issue.
As a result, I then tried writing it in javascript, and magic, it works! console.log() put out the results I am expecting. But, all my C++ program gets back is an object promise. I'm not a Javascript guy, and don't know what's going on.
So, my questions:
does emscripten_fetch() work with POST header data?
Can someone show me a javascript (EM_JS) version that works?
Gerald
Need to send a custom error message in keycloak script based authenticator.
On failure it showing same error message Incorrect email or password. Please check and try again. How to send a custom error message?
Code:
function authenticate(context) {
var username = user ? user.username : "anonymous";
var authShouldFail = false;
if (username=="anonymous") {
context.failure(AuthenticationFlowError.INVALID_CLIENT_CREDENTIALS);
return;
}
context.success();
}
I searched source code of keycloak repository and finally came up with a solution. The answer is to use setError method to show custom error messages and use context.failureChallenge function instead of context.failure like the following code:
// import the required Java classes
AuthenticationFlowError = Java.type("org.keycloak.authentication.AuthenticationFlowError");
Response = Java.type("javax.ws.rs.core.Response");
Errors = Java.type("org.keycloak.events.Errors");
function authenticate(context) {
var showCustomError = true; // you need to make your own controls to set this property
if (showCustomError) {
var errorMessage = "this is custom error message"; // set your custom error message
context.getEvent().error(Errors.IDENTITY_PROVIDER_ERROR);
var challengeResponse = context.form().setError(errorMessage, []).createErrorPage(Response.Status.INTERNAL_SERVER_ERROR);
context.failureChallenge(AuthenticationFlowError.IDENTITY_PROVIDER_ERROR, challengeResponse);
return;
}
context.success();
}
I am using masterkey yet still getting unauthorized error when trying to save an object. Can anyone figure out why? I can see that "started making ticket" gets logged. and the request.params all pull the correct information.
Also, a side question...I am under the impression that if response.error is executed it stops the code, but then will send that error message to the function that called this cloud code and then run any error handling there. I have a console.log error message in this cloud code, and then an error alert in the function that called it. I am getting the console log to show, but not the alert. Is my assumption wrong in that it doesnt get passed, and that it actually just terminates the entire thing upon executing response.error?
Parse.Cloud.define("createRecord", function(request, response) {
var caseClass = Parse.Object.extend("Cases");
var ticket = new caseClass();
console.log("started making ticket");
ticket.title = request.params.title;
ticket.category = request.params.category;
ticket.priority = request.params.priority;
ticket.description = request.params.cmnts;
ticket.save(null, {useMasterKey: true}).then(function() {
response.success();
}, function(error) {
response.error("error response: " + error.message);
});
Try this:
Parse.Cloud.run("createRecord", {something: yourData}, {...
and:
Parse.Cloud.define("createRecord", function (request, response) {
var something = request.params.something;
var caseClass = Parse.Object.extend("Cases");
var ticket = new caseClass();
console.log("started making ticket");
ticket.set("title", something.title);
ticket.set("category", something.category);
ticket.set("priority", something.priority);
ticket.set("description", something.cmnts);
ticket.save(null, {useMasterKey: true}).then(function() {
response.success();
}, function(error) {
response.error("error response: " + error.message);
});
Im trying to send a push message to everyone with read access every time a new note is saved.
In pseudocode it should get the ACL. Evaluate each member in the ACL and return an array of all users with read access. Then send a push notification to each member.
I've tried running separate task one by one and it works properly. However when I put everything together in the following code I get strange results. Looking at the log I can see it not executing in order as I expect. I first though the getACL call was an asynchronous call so I tried to implement promises with no luck. Then after help from stackoverflow I find out that getACL is not asynchronous therefore the code should just work, right?
This is what I'm trying:
Parse.Cloud.afterSave("Notes", function(request) {
var idsToSend = [];
var i = 0;
console.log("1 start");
var objACL = request.object.getACL();
var ACLinJSON = objACL.toJSON();
console.log("2 ACL = " + ACLinJSON);
for (var key in ACLinJSON) {
if (ACLinJSON[key].read == "true") {
idsToSend[i] = key.id;
console.log("3 i = " + i + " = " + idsToSend[i]);
i++;
}
}
console.log("4 idsToSend = " + idsToSend);
//lookup installations
var query = new Parse.Query(Parse.Installation);
query.containedIn('user', idsToSend);
Parse.Push.send({
where: query,
data: {
alert: "note updated"
}
}, {
success: function() {
console.log("Success sent push");
},
error: function(error) {
console.error("can’t find user"); //error
}
});
});
And this is the response I see from parse log
I2014-08-04T08:08:06.708Z]4 idsToSend =
I2014-08-04T08:08:06.712Z]2 ACL = [object Object]
I2014-08-04T08:08:06.714Z]1 start
I2014-08-04T08:08:06.764Z]Success sent push
Everything is completely out of order??
How can I execute the above function in the way it's written?
I've found the logs are not in order when I run things too, could be a timing issue or something, ignore the order when they're in the same second, I have done other tests to confirm things really do run in order on my own Cloud Code... had me completely confused for a while there.
The issue you're having is that log #3 is never being hit... try tracing ACLinJSON on it's own to see the actual structure. When you append it to a string it outputs [object Object] as you have seen, so do console.log(ACLinJSON); instead.
Here's the structure I've seen:
{
"*":{"read":true},
"Administrator":{"write":true}
}
Based on that I would expect your loop to work, but it may have a different level of wrapping.
UPDATE:
Turns out the issue was looking for the string "true" instead of a boolean true, thus the fix is to replace the following line:
// replace this: if (ACLinJSON[key].read == "true") {
if (ACLinJSON[key].read == true) {
My javascript:
var params = {};
params.selectedCurrency = 'USD';
params.orderIdForTax = '500001';
var xhrArgs1 = {
url : 'UpdateCurrencyCmd',
handleAs : 'text',
content : params,
preventCache:false,
load:function(data){
alert('success!');
},
error: function(error){
alert(error);
//the alert says 'SyntaxError: syntax error'
},
timeout:100000
};
dojo.xhrPost(xhrArgs1);
I tried debugging with firebug, i do get the appropriate response (i think). Here it is;
/*
{
"orderIdForTax": ["500001"],
"selectedCurrency": ["USD"]
}
*/
The comments /* and */ are somehow embedded automatically cuz the url im hitting with xhrPost is actually a command class on ibm's websphere commerce environment. Can anyone tell me what am i doing wrong here?
Server code
public void performExecute() throws ECException {
try{
super.performExecute();
double taxTotal;
System.out.println("Updating currency in UpdateCurrencyCmd...");
GlobalizationContext cntxt = (GlobalizationContext) getCommandContext().getContext(GlobalizationContext.CONTEXT_NAME);
if(requestProperties.containsKey("selectedCurrency"))
selectedCurrency = requestProperties.getString("selectedCurrency");
else
selectedCurrency = cntxt.getCurrency();
if(requestProperties.containsKey("orderIdForTax"))
orderId = requestProperties.getString("orderIdForTax");
OrderAccessBean orderBean = new OrderAccessBean();
cntxt.setCurrency(selectedCurrency.toUpperCase());
orderBean.setInitKey_orderId(orderId);
orderBean.refreshCopyHelper();
orderBean.setCurrency(selectedCurrency.toUpperCase());
orderBean.commitCopyHelper();
TypedProperty rspProp = new TypedProperty();
rspProp.put(ECConstants.EC_VIEWTASKNAME, "AjaxActionResponse");
setResponseProperties(rspProp);
}catch(Exception e){
System.out.println("Error: " + e.getMessage() );
}
}
The problem was with my client side code, weirdly.
load:function(data){
data = data.replace("/*", "");
data = data.replace("*/", "");
var obj = eval('(' + data + ')');
alert('Success');
}
Its weird but this worked. Lol.
I guess the problem is with coment-filtering option of handle as method.
The response should be comment filered as below.
See tha AjaxActionResponse.jsp (WCS)
vailable Handlers
There are several pre-defined contentHandlers available to use. The value represents the key in the handlers map.
text (default) - Simply returns the response text
json - Converts response text into a JSON object
xml - Returns a XML document
javascript - Evaluates the response text
json-comment-filtered - A (arguably unsafe) handler to preventing JavaScript hijacking
json-comment-optional - A handler which detects the presence of a filtered response and toggles between json or json-comment-filtered appropriately.
Examples