Our application crashes with the following (illogical) error message
“Error reading parameter aUserInfo: Unexpected class found in stream; class “TUserInfo” does not descend from “TUserInfo”.”
It looks like the issue is server related but I have to investigate this further.
I already posted this now because it is a blocking issue and maybe you already have an idea on what causes this.
FYI: I did not notice this at development time when testing with a single client on the same machine as the server. Possibly the issue surfaces easier with multiple clients
I will try to make a RO 10.0.0.1495 build of the server and see if the issue is fixed.
Any tips on what causes this or what resolves this are appreciated
FYI some extra info:
Apparantly I have had similar issues in the past which were fixed by making sure the Login function was called.
I think the issue is caused when the connection disappears (also in the past).
But now the issue occurs .
if True then // FVC 2018-08-07: Always enabled, we get EROException, Unexpected class found in stream; class "TUserInfo" does not descend from "TUserInfo". errors otherwise when opening 'verkoop' or 'bestellingen' - apparantly events received when not logged in screw up RO ClientParameters.AutoAanmeldenRobot then
begin
TRobotLogOnHelper.RobotLogin();
class procedure TRobotLogOnHelper.RobotLogIn();
{$ifndef OFFROBOT}
var
cguid : TGUID;
{$endif}
begin
{$ifndef OFFROBOT}
try
{ Calls the remote login method }
if assigned(dmGlobalRobot) then
begin
//dmGlobalRobot.Sum(1,2); // FVC TEMP
cguid := StringToGUID(dmGlobalRobot.Login(dmGlobalRobot.Identification));
dmGlobalRobot.SetClientId(cguid);
//dmGlobalRobot.BinMessage.ClientID := cguid;
// dmGlobalRobot.BinMessage_ER.ClientID := cguid;
end;
finally // wrap up
end; // try/finally
{$endif}
end;
Attached you can find the RODL and itf files rodlanditf.zip (23.9 KB)
A preliminary test with RO 10.0.1521 + a slightly older version of XE11 does not have the issue.
However looking at our crash history for all our customers (~1000 computers) we see from 5 to 20 crashes each month since 2018 (=beginning of our crash history)
So the issue was always there but occured in rare circumstances.
Try to change used channel with other one: Indy → Socket or Synapse, Socket ->Indy or Synapse, etc.
change server and client.
it is possible that tcp package is broken by some reasons during transmission so it cannot be read properly …
We are using delphi synapse (TROSynapseSuperTCPChannel/TROSynapseSuperTCPChannel) for both client and server
Our implementation has not changed in the recent years.
Our implementation works with RO 10.0.0.1521.
Are there external component changes between 1521 and 1537?
Are there internal changes that might explain this?
How can we make the code robuster? Looking at the callstack there is not much I can do on our side.
Any suggestions?
Is there any progress on this issue?
We now have to make releases using an 2 development machines (an old one which still has RO 1521 for the super tcp server).
What are you suggesting?
Should I add some code to my application?
For which purpose?
to solve the issue or to send you some data which you can investigate?
Are you suggesting I change my client side by hooking the ReceiveStream event?
If the code below OK?
I assume a lot of files will be generated.
How can we identify the stream which will result in the uncaught exception?
procedure TdmGlobalRobot2.ROSuperTCPChannelReceiveStream(aStream: TStream);
var
path,fname:string;
fs:TFileStream;
begin
if ls().FileLoggingEnabled then
begin
path:=IncludeTrailingPathDelimiter(OfficinallMainDir())+'log\robotclient';
if CreateDirectory(path,true) then
begin
fname := IncludeTrailingPathDelimiter(path)+'robotclientstream'+CreateFileNameDateTime(True,True)+'.bin';
fs:=TFileStream.Create(fname,fmCreate);
try
fs.CopyFrom(aStream);
finally
FreeAndNil(fs);
end;
end;
end;
inherited;
end;
FYI: My newly built client does not seem to crash on my local tests
I’ve been stresstesting it for the past few hours.
However I am not really confident since the problem in the past also occured more easily for our customers than in our development environment.
I am able to crash the old client executable however.
I also figured out that the apparant random crashes are not random but are caused each time another client registers.
So with the old code a single client works
but as of the second client login the previous clients throw an error
Our code:
function TRobotLoginService.Login(const UserId,machineName,extra: ROAnsiString): ROAnsiString;
var
newuser : TUserInfo;
RobotEvntswriter : IRobotEvents2_Writer;
msg_c_a : TMsgLogClientAdded;
msg2s : TMsgLogToSession;
begin
DmdStockRobot.LogMsg('TRobotLoginService.Login called for user '+UserId);
{ Checks if the user is already logged in }
if (fUsers.Search('UserID', UserId) <> NIL) then
raise Exception.CreateFmt('Client %s is already logged in'#13'Select an other ClientID', [UserId]);
{ Adds the user to the internal list of logged users }
newuser := fUsers.Add;
newuser.UserID := UserId;
newuser.SessionID := GUIDToString(Session.SessionID);
{ Stores the UserID of the user in the session.
This will be used in the OnLogout and OnSendMessage methods }
Session.Values['UserID'] := UserId;
result := newuser.SessionID;
RegisterEventClient(GuidToString(Session.SessionID), EID_RobotServerEvents2);
RegisterEventClient(GuidToString(Session.SessionID), EID_RobotEvents2);
// -- krg -- 31/08/2005 13:46:59 ------------------------------------------
// De code heeft eigenlijk geen nut (maar verwijderen we nie). De reden is
// simpel. Je client zal dit bericht nooit ontvangen omdat de SessionID nog
// niet toegekend is aan de client-kant.
try
if supports (EventRepository, IRobotEvents2_Writer, RobotEvntswriter) then
begin
RobotEvntswriter.SessionList.CommaText := Result;
{ Only broadcasts to the session listed in SessionList }
RobotEvntswriter.ExcludeSessionList := FALSE;
{ Generates the OnLogin event }
RobotEvntswriter.OnLogin(EmptyGUID, newuser);
end;
finally
RobotEvntswriter := nil;
end;
Meanwhile I think the cause of the issue is probably a name collision for 2 types with the name TUserInfo.
What happens for events when there is a new and an old intf file which contains
RegisterROClass(TUserInfo, DefaultNamespace);
in its initialization section?
They should be different (see attached files)
It is also unclear to me why the problem occurs now (with newer XE version and newer RO version but identical code: unit order in dpr is the same) RobotLibrary_Intf.pas (125.1 KB) RobotLibrary2_Intf.pas (226.3 KB)