XSharpPublic icon indicating copy to clipboard operation
XSharpPublic copied to clipboard

FieldPut in a table without data records - Error 5068: There is no current data record, but no exception in VO.

Open christianschmid200272 opened this issue 1 year ago • 6 comments

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.

christianschmid200272 avatar Aug 08 '24 08:08 christianschmid200272

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?

RobertvanderHulst avatar Aug 08 '24 09:08 RobertvanderHulst

Please note that at this moment FieldPut returns the uValue parameter and not a logical.

RobertvanderHulst avatar Aug 08 '24 09:08 RobertvanderHulst

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.

christianschmid200272 avatar Aug 08 '24 12:08 christianschmid200272

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?

RobertvanderHulst avatar Aug 09 '24 13:08 RobertvanderHulst

(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#.

RobertvanderHulst avatar Aug 11 '24 11:08 RobertvanderHulst

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.

christianschmid200272 avatar Aug 11 '24 13:08 christianschmid200272

Confirmed fixed

cpyrgas avatar Aug 23 '24 12:08 cpyrgas