Details
-
New Feature
-
Status: Closed
-
Major
-
Resolution: Fixed
-
None
-
None
-
None
-
Patch Available
Description
This allows javascript clients to be built for browser based access to thrift services.
The supported transport is XHTTPRequest and the supported Protocol is compatible with TJSONProtocol
I've added a test in lib/js that is a java based HTTP server which implements ThriftTest service.
I've put a version of this test service here http://3.rdrail.net:8080/test/test.html if you'd like to see it in action.
It's been tested in ie 6,7,8, FF, and Safari.
Let me know if you hit any issues. The protocol and transport code aren't very error tolerant, but overall it seems to work quite well.
Attachments
Attachments
- thrift_js.patch
- 104 kB
- T Jake Luciani
- thrift_js_v2.patch
- 86 kB
- T Jake Luciani
- thrift_js_v3.patch
- 87 kB
- T Jake Luciani
- THRIFT-550_initialize_with_null.patch
- 0.6 kB
- Roger Meier
Activity
Latest version. Includes misc bug fixes and added a async example in demo.
Take a look, I'll commit this in next couple days if no complaints.
I had a problem with the exception avaliable on the tutorial.
i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),
It couldn't be thrown because initialization of numeric base types is done with 0 instead of null and the checks do compare against null.
This was not visible with the Tests provided with first patch for JavaScript bindings above, the ThriftTest.thrift definition does not have a combination of a base type return value and an exception.
I've made a patch that initializes the base types I16,I32, I64 and DOUBLE with null. This could probably solve other issues as well
Regards
Roger
Can you open a new issue for this bug so it can be tracked separately?
Sure! I have created a new Bug Report for that issue:
https://issues.apache.org/jira/browse/THRIFT-807
Awesome project. You have no idea how helpful this is. I mean, could be quite helpful in the revolution of bring more complex client code to the front end. In addition, I can use the same service for my ajax webpage as I use for my iPhone app. A couple of issues:
1. Runtime exceptions. I would expect my operations to be able to accidentally throw an NPE/IllegalArgs (in Java) and have my js client catch them as follows:
catch(run) {
}
But it does not work. In some cases, the "run" is "undefined" and in other cases the auto-generated js bugs out.
Unfortunately it may be more complicated than we think. For service operations in the .thrift file that declare a checked exception (that was also defined in the .thrift file) I notice something in the auto-generated Java code.
For these operations that declare exceptions, there is a catch(Throwable) which transforms it into a TApplicationException.
Unfortunately, for service operations that do NOT declare an exception, it does NOT catch throwable which seems very odd to me. Whether or not something declares a checked exception has nothing to do with whether or not it throws runtime exceptions. I believe this is a bug, go see for yourself. Search for "public class yourOperationName implements ProcessFunction".
2. Now, that aside, I still see some problems on the js side of things.
For operations that do catch throwable on the client side, the js code tries to initalize a Thrift.ApplicationException.. Which doesn't exist. However there does appear to be something called Thrift.TApplicationException defined in thrift.js. Was this a bug?
3. I would like a nicer async api (I can show you what I hacked up at the bottom of the post.)
3. Once this is working, how can we catch exceptions from asynchronous methods? The async api I like would be the following:
SYNC API:
client.callMethod(param1, param2);
ASYNC API:
asyncClient.callMethod(handler, param1, param2);
With this api it won't work at all. We would need to supply another error handler. Oh well..
4. It would be cool to have nicer async clients: Here is some code I came up with that takes in a client and generates an asyncClient with all of the same methods, except that the first parameter is the callback (yes, we'll eventually need an error callback too.) (yes, it requires jQuery, but I think that we could just require that the user have it for async clients.)
function createAsyncThriftClient(syncThriftClient) {
var retObj = {};
for(var methodName in syncThriftClient) {
if(typeof syncThriftClient[methodName] === 'function') {
if(methodName.substring(0,5) == "send_" || methodName.substring(0,5) == "recv_")
else
{ retObj[methodName] = createThriftAsyncCall(syncThriftClient, methodName) } }
}
return retObj;
}
var createThriftAsyncCall = function(syncThriftClient, methodName) {
return function() {
var calledMethodName = methodName;
if(arguments.length < 1)
var successHandler = arguments[arguments.length-1];
var apiArgs = new Array();
for(var i = 0; i < arguments.length-1; i++)
jQuery.ajax({
url: "/service",
data: syncThriftClient["send_" + calledMethodName].apply(syncThriftClient, apiArgs),
type: "POST",
cache: false,
success: function(res)
});
}
};
EDIT: Actually, that code requires the callback as the last parameter to the assync.methodCall().
UPDATE:
I just tried throwing a CHECKED exception (that was declared in the .thrift file) from a sync client (which I though was working) and it seems like the exception that was caught is not at all related to the one that was thrown.
Instead the caught exception is related to "this.robj is undefined."
I do understand that the test cases are working fine, and those exceptions are being caught properly in the js, but mine are not. I can't find what is different. I practically copied the code and just renamed the Exception and the service operation, yet it won't catch mine.
What can I do, if anything, to help get this problem fixed. I don't understand much about this project, but it's important that exceptions get translated into javascript correctly.
Hi Jordan,
I had similar issues with exceptions! That's why I've added a patch to fix this, see above or have a look on the newly created issue:
https://issues.apache.org/jira/browse/THRIFT-807
Roger
Roger,
I took a look at that. Thank you. I did mention in that Jira item that my operation returns a boolean, not void and not i32, and I asked you in that jira task if your patch will fix that as well. If you could, could you please answer that question in that jira task thread? Thank you.
Also, supposing that exceptions ARE indeed thrown correctly. What happens with a runtime exception? What do you think SHOULD happen with a runtime exception. It seems from the service side, we should never let an unchecked exception be thrown back to the client. In the java generated code, it masks them as TApplicationException, which is good, but can you verify that the way it does that is broken? Look at an operation that does not declare an exception. Notice how it does not catch throwable and transform to TApplicationException.
Granted, I think it's wise to declare that all of your operations throw YourMadeUpServiceException.
Next iteration of patch.