DEFINE CLASS MyClass As Session OlePublic Function SaveMyWork( oRs1, ors2 ) LOCAL loContext This.Rs1 = oRs1 This.Rs2 = oRs2 *-- Create your object context here lnResult1 = This.SaveRs( oRs1 ) && Save an ADO Recordset with some data x = y && This causes an error and causes the program to stop executing because the error method call ComReturnError() *-- At this point the control is given back to the client *-- The SetAbort() is not called, SetComplete() is the default *-- So the changes to the database will be committed even if oRs2 was not saved *-- Even Worst is i stored the 2 RecordSets in This.Rs1 And This.Rs2 *-- and my GC Method is not called so i will for sure get a C5 at some later time when running this method again. lnResult2 = This.SaveRs( oRs2 ) && Save an ADO Recordset with some data IF lnResult1 = 0 AND lnResult2 = 0 *-- Call setComplete() ELSE *-- Call SetAbort() ENDIF ENDFUNC **-- Some more functions here including a error function with ComReturnError() ENDDEFINEAs you can see, ComreturnError() is the problem here, as you say we should keep an open mind, and i don't say there is no use for ComReturnError(), i just say it is very dangerous to use it without understanding it fully.
>>>>DEFINE CLASS MyClass As Session >>>> >>>> ErrorText = "" >>>> ErrorOccured = .F. >>>> PROTECTED ErrorText, ErrorOccured >>>> >>>> Function SomeFunction( cPar ) >>>> LOCAL lcResult >>>> >>>> *-- Create Your MTS Object context Here >>>> >>>> *-- Do some processing to build lcResult >>>> lcResult= GetSomeXmlString() >>>> IF This.ErrorOccured >>>> lcResult = This.ErrorText >>>> ENDIF >>>> >>>> *-- Call SetComplete() Or SetAbort() Here >>>> >>>> RETURN lcResult >>>> >>>> ENDFUNC >>>> >>>> PROTECTED FUNCTION Error( p1,p2,p3 ) >>>> This.ErrorOccured = .T. >>>> This.ErrorText = GetXmlErrorString(p1,p2,p3) >>>> ENDFUNC >>>> >>>>ENDDEFINE >>>>>>>>>However, for a stateless COM application like a web app (vfp mtdll), ALWAYS use ComReturnError. This is a good rule-of-thumb for web apps.