EROUnregisteredServerException

Trying to debug an issue in my server and I’m getting some occurrences of an EROUnregisteredServerException which is passed down to the client, so it’s actually the client that throws an error but says the error occurred on the server.

How can I trap this on the server and actually see what the underlying error is and/or where it’s actually happening?

Hi,

this error is raised on client-side when client-side can’t detect actual error type.

the logic is:

function TROMessage.CreateException(const aExceptionName, aMessage: string): Exception;
var
  lExceptionClass: ExceptionClass;
begin
  lExceptionClass := GetExceptionClass(aExceptionName,fDefaultNamespacesList);

  if Assigned(lExceptionClass) then begin
    // The exception was registered so we can reraise the right type
...
  end
  else begin
    // Un-registered exception. We fire a EROUnregisteredServerException
...
  end;
end;

Is there any way I can disable this handling?

The underlying exception is just a generic “Access violation at address…” so I have no idea what happened or where. How can I trap this on the server?

Hi,

you can override default TROInvoker.CustomHandleMessage method with your own like

function TMyServiceInvoker.CustomHandleMessage(const aFactory: IROClassFactory;
  const aMessage: IROMessage;
  const aTransport: IROTransport;
  out oResponseOptions: TROResponseOptions): boolean;
begin
  try
     result := inherited CustomHandleMessage(...);
  except
    on E: EAccessViolation do raise ...
    ...
    on E: Exception do raise;
  end;
end;

Thanks will have a look

Don’t quite understand how I override the Invoker classes. These are auto-generated in the …Invk.pas file - surely if I change them the file will just be regenerated when I recompile?

Hi,

you have in _impl something like

initialization
  fClassFactory_NewService := TROClassFactory.Create(__ServiceName, Create_NewService, TNewService_Invoker);

so create descendant of TNewService_Invoker and use it as a default for your service:

type
  TMyNewService_Invoker = class(TNewService_Invoker)
  protected
    function CustomHandleMessage...
  end;

function TMyNewService_Invoker.CustomHandleMessage...

initialization
  fClassFactory_NewService := TROClassFactory.Create(__ServiceName, Create_NewService, TMyNewService_Invoker);

Ah of course, thanks.

Is there a way to register a class exception at server in order to verify the class type at client and process it accordingly ?

Hi,

usually adding a exception to RODL in Service Builder is enough.
Pls check the MegaDemo sample - a custom exception is raised on server-side and passed to client.