FieldPut in a table without data records - Error 5068: There is no current data record, but no exception in VO.
If you try to write a value to an open, empty table in X# without first checking whether there is a data record, an exception is thrown. No exception is thrown in VO.
FUNCTION Start() AS VOID STRICT
LOCAL cDbf AS STRING
cDbf := "c:\Test\fieldput"
RddSetDefault("AXDBFCDX")
AdsSetServerType(1)
FErase(cDbf + ".cdx")
DbCreate(cDbf, {{"KENNZ","C",3,0}})
DbUseArea(,,cDbf)
FieldPut(1,"n")
DbCloseArea()
RETURN
Description : Error 5068: There is no current record. Subsystem : AXDBFCDX GenCode : EG_WRITE Write error SubCode : 5068 Error 5068: There is no current record. FuncSym : FieldPut Severity : ES_ERROR Can Default : False Can Retry : False Can Substitute : False FileName : c:\Test\ordkeyno.dbf Stack Trace : ADSRDD:ADSERROR (Line: 0) ADSCHARACTERCOLUMN:PUTVALUE (Line: 0) ADSRDD:PUTVALUE (Line: 0) COREDB:<>C__DISPLAYCLASS49_0:<FIELDPUT>B__0 (Line: 0) COREDB:DO (Line: 0) COREDB:FIELDPUT (Line: 0) FIELDPUT (Line: 0) START (Line: 16)
We use X# runtime version 2.20.0.3.
Christian, What would you expect in this situation? Should FieldPut "silently" swallow the error and return FALSE? Are you checking for the return value of FieldPut in your code?
Please note that at this moment FieldPut returns the uValue parameter and not a logical.
Robert, we don't currently check the return value, but basically if FieldPut returned a boolean value I would expect false if it didn't work and true if it did. Also a uValue as return value is ok to check for NiL but not an unhandled exception. With more than 10000 FieldPut calls, the affected position cannot really be identified.
I checked VO and it indeed "swallows" this error. Id DOES however throw an error when the FieldPut fails when the current record is not locked. I do not think we can change the return value of FIeldPut() to logic. That will break too much code. At this moment the source of FieldPut is this:
FUNCTION FieldPut (nFieldPos AS USUAL, uNewValue AS USUAL) AS USUAL
LOCAL lResult AS LOGIC
IF ! IsNumeric(nFieldPos)
THROW Error.ArgumentError( __FUNCTION__, nameof(nFieldPos), __CavoStr(VOErrors.ARGNOTNUMERIC), 1 ,<OBJECT>{nFieldPos,uNewValue})
ENDIF
lResult := VoDb.FieldPut(nFieldPos, uNewValue)
IF ! lResult
IF RuntimeState.Dialect == XSharpDialect.XPP
uNewValue := NIL
ELSE
DoError(__FUNCTION__)
ENDIF
ENDIF
RETURN uNewValue
FYI: DoError() is the function that throws the error. I can change the code to return NIL when it fails for all dialects, except when it fails because of a locking error (just like in VO) Would that make sense?
(Of course) I don't have the source for the VO ADS RDD. But I see that in VO for both DBFCDX and AXDBFCDX no error is thrown when you do a FieldPut() as EOF. In fact also VoDbFIeldPut() returns true. I will change that in X#.
It is not necessary to change the return value of FieldPut, the applications have worked with the "uValue" so far. For your information, I'm on vacation for the next week just in case there are any questions. Thanks for the customization.
Confirmed fixed