Exception: Invalid GUID:?

Hi,

Since upgrading to Delphi 10.2 and the latest version of DA, I’m getting this error when posting to a certain table:

An exception was raised on the server: Invalid GUID: ???.

I’m using FireDAC against an MSSQL database. The table in question has a GUID type column which I’m initialising using NewGUID in the client rules’ AfterInsert handler. The client populates the remaining columns and then posts the change and calls ApplyUpdates.

The server then throws this error. If I run the server in debug mode to try to trap the error, it’s deep in the bowels of the DA code when it’s executing the INSERT it has created on the fly. The error is reported as:

Project XXX raised exception class EConvertError with message ‘‘㑻㤳い䘲ⵆ䔰䈸㐭㌴ⴳあ㜰ㄭㅅ〷䘰㜸䐵絆’ is not a valid GUID value’.

The call stack at this point is:

:74acdb18 KERNELBASE.RaiseException + 0x48
:00428b46 ConvertErrorFmt + $1E
:00428c5d StringToGUID + $35
:00a9e0c4 TFDParam.GetAsGUIDs + $60
:00a9b45c TFDParam.GetData + $43C
:00bb4c76 ProcessArrayItem + $23A
:00bb4f6a TFDPhysODBCCommand.SetParamValues + $18E
:00bb54bc TFDPhysODBCCommand.InternalExecute + $EC
:00b95d6b Process_HandleSystemFailure + $6B
:00b95e9f Process_SingleRow + $47
:00b96df4 TFDPhysCommand.ExecuteBase + $1FC
:00b958b6 TFDPhysCommandAsyncExecute.Execute + $E
:00b52503 TFDStanAsyncExecutor.Run + $73
:00b906c8 TFDPhysCommand.ExecuteTask + $124
:00b97000 TFDPhysCommand.Execute + $60
:00b21b2d TFDCustomCommand.InternalExecute + $FD
:00b21df4 TFDCustomCommand.Execute + $30
:00b2817a TFDAdaptedDataSet.DoExecuteSource + $32
:00b2a495 TFDCustomQuery.ExecSQL + $D
uDAEBaseDataset.TDAEBaseDataset.Execute
uDABusinessProcessor.TDABusinessProcessor.ProcessDelta(TDAEFireDACConnection($87FA804) as IDAConnection,TDADelta($87A61E0) as IDADelta,[ctInsert,ctUpdate,ctDelete],$D048910)
DataAbstractService_Impl.TDataAbstractService.BP_ProcessChanges($D048910,[ctInsert,ctUpdate,ctDelete],True)
DataAbstractService_Impl.TDataAbstractService.UpdateData_StandardMode($D048A70)
DataAbstractService_Impl.TDataAbstractService.InternalUpdateData((TDADelta($87A61E0) as IDADelta),False)
DataAbstractService_Impl.TDataAbstractService.UpdateData(???)
ActivitiesService_Impl.TActivitiesService.UpdateActivityData($8711010,???)
Clarity_Invk.TActivitiesService_Invoker.Invoke_UpdateActivityData(TActivitiesService($769453C) as IInterface,TROBinMessage($8809944) as IROMessage,TROSCServerWorker($75F0AD8) as IROTransport,)
uROServer.TROInvoker.CustomHandleMessage(TROClassFactory($8828DB4) as IROClassFactory,TROBinMessage($8809944) as IROMessage,TROSCServerWorker($75F0AD8) as IROTransport,)
uROServer.TROInvoker.HandleMessage(???,???,TROSCServerWorker($75F0AD8) as IROTransport,)
uROServer.MainProcessMessage(TROBinMessage($8809944) as IROMessage,TROSCServerWorker($75F0AD8) as IROTransport,???,$8710E30,,True)
uROServer.TROMessageDispatcher.ProcessMessage(TROSCServerWorker($75F0AD8) as IROTransport,$8710D90,$8710E30,,True)
uROServer.TROServer.IntDispatchMessage($87DDD60,TROSCServerWorker($75F0AD8) as IROTransport,$8710D90,$8710E30,)
uROServer.TROServer.DispatchMessage(TROSCServerWorker($75F0AD8) as IROTransport,$8710D90,$8710E30,)
uROServer.TROServer.DispatchMessage(???,???,$8710E30)
uROBaseSuperTCPServer.TROInvokerQueueItem.Callback(???,???)
uROThreadPool.TROPooledThread.IntExecute
uROInitializedThread.TROInitializedThread.Execute
:004d66a8 ThreadProc + $4C
:0040bce2 ThreadWrapper + $2A
:747f38f4 KERNEL32.BaseThreadInitThunk + 0x24
:77675de3 ;
:77675dae ;

This is a total show-stopper for me right now and I can’t figure out what’s going on. Has something changed with regards to GUIDs in the latest version? Is this another FireDAC issue?

FWIW I tried switching from FireDAC to the MS Native Client for MSSQL to check if it was FireDAC but then I start getting an invalid pointer operation during a command execution elsewhere.

Don’t know what on earth is going on any more, this was all working fine under XE6 and the previous version of DA.

can you create a simple testcase, that reproduces this?
you can attach it here or send directly to support@ .

I’m just in the process of doing this now - just to see if it happens with a fresh test project

GUIDTest.rar (110.7 KB)

Here you go - test server and client project created using the wizard. There’s an SQL file in there too to create the database itself. This throws the above error for me when I hit the button on the client.

Thanks, logged as bugs://77858

bugs://77858 got closed with status fixed.

pls update uDABin2DataStreamerSupport.pas as

function Bin2_ReadVariantFromStream(Stream: TStream; DataType: TDADataType): Variant;
..
    datGuid: Result := AnsiBytesToString(Bin2_ReadGUIDFromStream(Stream)); //<<<<<<<<<changed

Thanks will give it a go. Is this another FireDAC change/issue by any chance?

not yet.
it just incorrectly translates content of TBytes into Variant so we need to use TBytes->String->Variant for getting valid Guid

Yes that’s fixed it, thanks.

So is this something they’ve changed in Delphi itself? Just trying to understand why this has suddenly started happening.

we have stopped usage of AnsiString & UTF8String in favor of String for compatibility with NEXTGEN compiler and looks like case with guid processing was missed from our tests or it was tested with non-unicode versions of Delphi only.

Ah ok that makes sense. I’d already noticed the removal of UTF8Strings, primarily in the logon service.

I’m now investigating another very weird error in our code which seems similar.

I’m getting an exception thrown during an ApplyUpdates which is because a GUID string value is incorrect, containing only an opening curled brace. I’m not sure why this is yet but, when the ProcessError function of my business processor is called, it appears that all the string values accessed via the strongly typed properties are corrupted and displaying as random Chinese characters.

This appears only to happen when a LocalDataAdapter is used on the server itself. When an RDA is used on the client it’s fine.

Do you have any ideas on this as I’m lost and, given the previous issues with strings, I’m concerned it could be something related.

can you create a simple testcase, pls?
from symptoms - it seems that widestring was read as ansistring …

That could be tricky as I’m not entirely sure what’s going on just yet but I’ll try.

Here you go. Again a simple test project created using the wizard with an SQL script to create the database.

As you can see, it works client-side but not server-side, seems to be an issue with the LDA and nvarchar(max) fields.

StringTest.rar (112.8 KB)

Thanks, logged as bugs://77941

bugs://77941 got closed with status fixed.

pls update uDALocalDataAdapter.pas as

  procedure SetDestValues_BatchMode;
  var
    s: UnicodeString;  //changed
..
              datGuid: begin
                buf3:= StringToAnsiBytes(VarToStr(val[i]));
                Move(buf3[0], pointer(buf1)^, 38 {Length(GuidString)});
              end;
              datBlob,
              datMemo: begin
                buf3 := VariantToBytes(Val[i]);
                PPointer(buf1)^ := aDataForAppend.lBatchAdding.MakeBlobFromBytes(buf3);
              end;
              datWideMemo,
              datXml:begin
                s := VarToUnicodeStr(Val[i]);
                c:=Length(s)*SizeOf({$IFDEF UNICODE}Char{$ELSE}WideChar{$ENDIF});
                SetLength(buf3,c);
                if c > 0 then Move(s[_StrLow],buf3[0],c);
                PPointer(buf1)^ := aDataForAppend.lBatchAdding.MakeBlobFromBytes(buf3);
              end;

Note: This fix will be in next week’s beta.