-
-
Notifications
You must be signed in to change notification settings - Fork 367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error handling in JSONRPC #538
Comments
Good point. Let me think a bit about it. |
Thanks, I'll prototype a change in the next few days. |
Will need to include some type of json unit in the core MVCFramework unit if we want to surface the error object - thoughts ? |
Sorry to be late at reply. |
I got as far as adding the following code, it does not yet deal with the JSON error object
I'll take a look at passing through the error JSON object in the next iteration |
If I change the signature of the Exception handler, I'll need to add a JSON unit to the uses clause in the MVCFramework.pas file. This will then bind the whole library whatever library is used e.g. System.Json or JsonDataObjects Do you have a preference or can this be better handled via conditional compilation ?
|
dmvcframework uses jsondataobject not system.json so it's ok to use jsondataobject |
Why not pass only the relevant properties as string and integer?
We don't need to pass a "JSON error" there, we can pass just the info to describe it. |
The object that is created within the JSONRPC controller encapsulates: If I pass these as individual params, then the framework will need to deal with any changes to them. Also by passing the JSON object, it allows the application developer to add fields to the object which can be used by the front end js developer. Another alternative would be to pass the JsonObject as a var string, and then parse it back to the lJSONResp variable. E.g. if the exception passes then the application writer could change it to This would then be sent back to the client. Apart from some loss of efficiency with the additional conversion from JsonObject to string and back, this would give flexibility, and decouple the main MVCFramework from any particular JSOn library. What do you think ? Edited to rename the extra field in the return value (I had missed your change in the comment above) |
I'll take a look at the linked in specification (thanks for the link) |
So I'm proposing to change signature of the anonymous procedure to
Still not sure if the Controller needs to be passed through though. And the relevant code change in the JSONRPC call is
with a new local var to allow the string to be passed and altered |
Here's a patch file for the JSONRPC unit, the MVCFramework unit just has the changes as above (ext changed to txt to allow upload to github) |
I've tested this with some of our code, here's an example of the code in the webmodule
And by raising an exception in the TEventFunctions method I get the following back at the browser
|
Passing a Json object (also as string) could break the protocol because user could not respect the errorobject specs. We need to pass a record by var or something else. Then the framework will recreate the error object using the provided data. |
I'd then have to declare the record in the main MVCFramework.pas file, which kind of pollutes that file with JsonRPC related structures. So I'm not keen on that direction. The specification allows the optional "data" field to be either Primitive (i.e. string or number) or Structured such as a object or array.
Using TValue would require a signature like
with corresponding unpacking in the controller code. |
Yes, this could be an approach that I like. Another could be to limit the generic nature of data and define it as TMVCStringDictionary |
I'm not sure what a string dictionary would bring, when the spec says that "data" can be either Primitive or Structured.
I'm not sure how you could do that with the dictionary. |
Yes, that's true. A dictionary would simple to implement but not flexible as specs recommends. |
On reflection, it is not really much different from the "result" field in the case when there is no error. The spec says "The value of this member is determined by the method invoked on the Server." so there is really no constraint apart from what the server decides to send back. In the same way the "data" sub field of the "error" field, as per 5.1 on the spec, is open ended and is up to the server to determine. So I do think that TValue, or json formatted string are the best options. |
OK, let's go with the TValue and we'll see how it works. |
Ok I've got some code changes to implement this. So the relevant part of MVCFramework.pas looks like
I've left the ref to the controller in there, commented out as it is YAGNI at this stage. I'll make a diff file for the JsonRPC file changes and attach it to a separate post. |
Here's the patch for the MVCFramework.JSONRPC.pas. file |
I've done the following tests:
which outputs
which outputs
In this case the client and server would need to understand how to populate/use the contents of the data field, which is outside the scope of the spec, but is allowed as an extensibility mechanism. |
Thanks David for you contribute. I merged your code and did some slight changes. Please, test from your POV and let me know. |
Thanks for the refinement. Although I'm getting an error when the Data object is freed by the framework, I'll look into it.
The code blows up at
which is caused by
|
Found it, the assigned Data object is already being freed here
However in the exception handling code that the app developer writes, if the ExceptionHandled parameter remains false, then the framework will not assign the Data field so, the framework is responsible for freeing the item. I will create a patch. |
Here's a patch. As ownership (and then freeing) only happens when the ExceptionHandled is true, I've added that to the test. Also I think when the Data property of the TJSONRPCResponseError class is assigned (it calls SetData), then it should free any existing TObject, so the patch reflects that as well. |
Merged your changes. Let me know. |
Thanks, looks like we have a solution :) |
Thanks a lot for your support, David |
The Index method in the TMVCJSONRPCController has a try/except code block that handles all Exception types.
This means that an application writer is prevented from writing a high level exception handling block that allows custom exception handling as in the normal RESTful mvc application, because all custom error classes are descendants of Exception so get caught.
For instance It prevents an application from being able to log nested exceptions, and also log the call stack using 3rd party code such as Eurekalog.
Issue #191 added a custom exception handler to address this issue for RESTful applications.
I propose a similar pattern for JSONRPC, which would be called from the exception block on the TMVCJSONRPCController.Index method.
Useful objects to pass through are:
Thoughts ?
The text was updated successfully, but these errors were encountered: