Index: MVCFramework.JSONRPC.pas =================================================================== diff --git a/DMVC/sources/MVCFramework.JSONRPC.pas b/DMVC/sources/MVCFramework.JSONRPC.pas --- a/DMVC/sources/MVCFramework.JSONRPC.pas (revision 207) +++ b/DMVC/sources/MVCFramework.JSONRPC.pas (working copy) @@ -372,6 +372,7 @@ TMVCJSONRPCController = class(TMVCController) private + fExceptionHandler: TMVCJSONRPCExceptionHandlerProc; fSerializer: TMVCJsonDataObjectsSerializer; fRPCInstance: TObject; fOwsRPCInstance: Boolean; @@ -408,7 +409,8 @@ TMVCJSONRPCPublisher = class(TMVCJSONRPCController) public - constructor Create(const RPCInstance: TObject; const Owns: Boolean = True); reintroduce; overload; + constructor Create(const RPCInstance: TObject; const Owns: Boolean = True; ExceptionHandler: TMVCJSONRPCExceptionHandlerProc = nil); + reintroduce; overload; end; TJSONRPCProxyGenerator = class abstract @@ -821,11 +823,13 @@ { TMVCJSONRPCController } -constructor TMVCJSONRPCPublisher.Create(const RPCInstance: TObject; const Owns: Boolean); +constructor TMVCJSONRPCPublisher.Create(const RPCInstance: TObject; const Owns: Boolean = True; ExceptionHandler: + TMVCJSONRPCExceptionHandlerProc = nil); begin inherited Create; fRPCInstance := RPCInstance; fOwsRPCInstance := Owns; + fExceptionHandler := ExceptionHandler; end; // procedure TMVCJSONRPCController.CheckInputParametersTypes(aRTTIMethod: TRTTIMethod); @@ -1147,6 +1151,8 @@ lTypeAttrs: TArray; lHTTPVerb: TMVCHTTPMethodType; lAllMethodsCallableWithGET: Boolean; + lExceptionHandled: Boolean; + lJSONRespErrorObj: TMVCJSONRPCExceptionErrorObject; begin lBeforeCallHookHasBeenInvoked := False; lAfterCallHookHasBeenInvoked := False; @@ -1347,9 +1353,26 @@ begin lJSONResp := CreateError(lReqID, 0, Ex.Message); LogE(Format('[JSON-RPC][CLS %s][MSG "%s"]', [Ex.ClassName, Ex.Message])); + if Assigned(fExceptionHandler) then + begin + lExceptionHandled := true; + lJSONRespErrorObj.Code := 0; + lJSONRespErrorObj.Msg := Ex.Message; + lJSONRespErrorObj.Data := nil; + fExceptionHandler(Ex, Context, lJSONRespErrorObj, lExceptionHandled); + if not lExceptionHandled then + raise; + lJSONResp.O['error'].I['code'] := lJSONRespErrorObj.Code; + lJSONResp.O['error'].S['message'] := lJSONRespErrorObj.Msg; + if not lJSONRespErrorObj.Data.IsEmpty then + begin + TValueToJSONObjectProperty(lJSONRespErrorObj.Data, lJSONResp.O['error'], 'data'); + if lJSONRespErrorObj.Data.IsObjectInstance then + lJSONRespErrorObj.Data.AsObject.Free; + end; + end; end; end; // except - if lBeforeCallHookHasBeenInvoked and (not lAfterCallHookHasBeenInvoked) then begin try