Exception Handler setting not working

Feb 27, 2014 at 12:15 PM
Edited Feb 27, 2014 at 2:31 PM
Hello Guys,

I've followed the documentation to set a global error handler for JSON rpc processing. See code below:
public void startControlService(settings.GenericSetting portSetting) 
{
      //
      this.port = Int32.Parse(portSetting.value);
      //
      setJSONRPCExceptionHandler();
      //
      cs = new ControlService();
      server = new JsonSocketListener.AsyncJsonRPCServer(port);
      listenThread = new Thread(new ThreadStart(server.startListening));
      listenThread.Start();
}
First, I attempt to attach my custom error handler to the framework. Then I create my service object (which inherits JSONService), and then I start my listener.

SetJSONRPCExceptionHandler contains:
private void setJSONRPCExceptionHandler()
{
     AustinHarris.JsonRpc.Config.SetErrorHandler(OnJsonRpcException);
}
Lastly, my handler method is as per the documentation:
private JsonRpcException OnJsonRpcException(JsonRequest rpc, JsonRpcException ex)
{
    EngageUtilities.WindowsEventLogHandler.logError(this, String.Format("Invalid JSON Request received: {0}.", rpc.ToString()));
    return new JsonRpcException(-10000, String.Format("Invalid JSON Request received: {0}.", rpc), ex.Message);
}
Whenever I generate an error (by supplying invalid JSON requests, which is what I'd like to catch), my OnJsonRpcException method is never reached. I can't see what I'm doing wrong. Any ideas, or can someone point me in the right direction?

Thanks,
Jan Breens
Feb 27, 2014 at 2:35 PM
Hello Guys,

Some more info. The code above is reached, but only when my code generates and Exception. What I'm trying to prevent, is the user receiving full stack traces when sending invalid JSON to the server. Currently, something like this is sent back:
{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error","data":{"ClassName":"Newtonsoft.Json.JsonReaderException","Message":"Unexpected character encountered while parsing value: a. Path '', line 0, position 0.","Data":null,"InnerException":null,"HelpURL":null,"StackTraceString":"   at Newtonsoft.Json.JsonTextReader.ParseValue()\r\n   at Newtonsoft.Json.JsonTextReader.ReadInternal()\r\n   at Newtonsoft.Json.JsonTextReader.Read()\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)\r\n   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)\r\n   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)\r\n   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)\r\n   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)\r\n   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value)\r\n   at AustinHarris.JsonRpc.JsonRpcProcessor.ProcessJsonRpcState(String sessionId, JsonRpcStateAsync async, Object jsonRpcContext) in c:\\Users\\Austin\\Documents\\Visual Studio 2012\\Projects\\AustinHarris.JsonRpc\\Json-Rpc\\JsonRpcProcessor.cs:line 59","RemoteStackTraceString":null,"RemoteStackIndex":0,"ExceptionMethod":"8\nParseValue\nNewtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed\nNewtonsoft.Json.JsonTextReader\nBoolean ParseValue()","HResult":-2146233088,"Source":"Newtonsoft.Json","WatsonBuckets":null}},"id":null}
I'd like to make that slightly cleaner, should this be handled a different way?

Cheers,
Jan
Coordinator
Feb 27, 2014 at 9:02 PM
Edited Feb 27, 2014 at 9:40 PM
Hi Jan,

Sorry that your having issues with the exception handling.

Sadly you are correct that : Config.SetErrorHandler(); Only handles Errors that are thrown in your code, and not errors thrown in parsing.

There is a workaround, though it is not as clean as it could be.

**
Removed incorrect recommendation. See below
**
Coordinator
Feb 27, 2014 at 9:30 PM
Edited Feb 27, 2014 at 9:42 PM
I was incorrect in my previous recommendation, as you do not get a "JsonRpcResult" back from the Processor. Instead you get a string back from the Processor.

To address this in a clean way you will have to make some custom modifications to the source code.

I would recommend pulling down a copy of the source code that Matches the current build you are using. Don't pull the latest version, as it is not proven. (Should be version: 22265 https://jsonrpc2.codeplex.com/SourceControl/changeset/22265)

Then you will have to modify JsonRpcProcessor.cs as seen in: https://jsonrpc2.codeplex.com/SourceControl/latest#AustinHarris.JsonRpc/Json-Rpc/JsonRpcProcessor.cs

You can refactor it so that it calls Handler.GetSessionHandler(sessionid).externalErrorHandler (Which is currently a private member, that you need to make Internal so that the Processor can call it) prior to every Return statement that sets the Error property.