#1 2020-07-14 12:24:42

damiand
Member
From: Greece
Registered: 2018-09-21
Posts: 94

Exception in a service method with a record parameter

I have a record definition like this:

  TMyClient = packed record
    Afm: RawUTF8;
    Eponymia: RawUTF8;
    Epaggelma: RawUTF8;
    Diefthynsi: RawUTF8;
    Doy: RawUTF8;
  end;

In a service interface a var parameter of this type is passed to be filled by the service:

  IInvoice2Bills = interface(IInvokable)
...
    function GetClientInfo(const afm: RawUTF8; var clInfo: TMyClient): integer;
...
  end;

When I'm attempting to call this method from a client I'm getting an EInterfaceFactoryException with message:

'TInterfacedObjectFakeClient.FakeCall(IInvoice2Bills.GetClientInfo) failed: '{
"errorCode":406,
"errorText":"IInvoice2Bills.GetClientInfo failed on clInfo:TMyClient [returned record]"
}''

In the server I can call this method without problem. Any advice is (very) appreciated.

Last edited by damiand (2020-07-14 12:26:34)

Offline

#2 2020-07-14 12:54:39

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,272
Website

Re: Exception in a service method with a record parameter

Which compiler do you use?

Did you register the record with its text definition?

Offline

#3 2020-07-14 13:12:33

damiand
Member
From: Greece
Registered: 2018-09-21
Posts: 94

Re: Exception in a service method with a record parameter

For the client (32 bit) Delphi 10.3.3 Community. For the server lazarus/fpc 64 bit on linux. I didn't register the record and I suspect that this is the cause. How do I do this? I'll take a look in the documentation.

Offline

#4 2020-07-14 14:44:55

damiand
Member
From: Greece
Registered: 2018-09-21
Posts: 94

Re: Exception in a service method with a record parameter

Following the documentation: https://synopse.info/files/html/Synopse … #TITLE_242

I added to my interface definition unit constants the following:

  __TMyClient = 'Afm RawUTF8 Eponymia RawUTF8 Epaggelma RawUTF8 Diefthynsi RawUTF8 Doy RawUTF8';

and in the initialization section of the same unit I added (just above the TInterfaceFactory.RegisterInterfaces call), the following line:

  TTextWriter.RegisterCustomJSONSerializerFromText(TypeInfo(TMyClient),__TMyClient);

After I recompiled the server and the client, the problem solved. smile

However, according to the documentation this should have already been happened by the framework itself, since the Delphi compiler creates RTTI for the record definition. Probably the FPC 3.2.0 in Linux didn't create such RTTI in the server's code. To put my 2 cents on this, when I examined the outcome of the RecordSaveJSON call in the FPC server code (before the application of the above),  I got binary format. On the contrary, on the Delphi/Windows 10 client I got text JSON.

Offline

#5 2020-07-14 15:25:04

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,272
Website

Re: Exception in a service method with a record parameter

The RTTI is available only on Delphi 2010+.
On FPC - so on your server - it is not available.
It is clearly documented as such.

So my advice is to always define the records as text.
As a benefit you could rename the record fields in code, but keep the JSON representation.

Hint: you may write for your definition:

__TMyClient = 'Afm,Eponymia,Epaggelma,Diefthynsi,Doy: RawUTF8';

Offline

Board footer

Powered by FluxBB