Discussions
Categories
Groups
Community Home
Categories
INTERNAL ENABLEMENT
POPULAR
THRUST SERVICES & TOOLS
CLOUD EDITIONS
Quick Links
MY LINKS
HELPFUL TIPS
Back to website
Home
Content Management (Extended ECM)
API, SDK, REST and Web Services
FetchVersion (and maybe other func calls) bug and temporary solution
Louis_Routhier
This morning, I was working on our LAPI wrapper libraries, testing it using NUnit when I decided to add some new tests to validate the behaviour when a non existent version number was requested on a document. I must say I was half surprised when I got the following exception:"LLValue unknown field name: FileAttributes"Since this exception was almost useless (there is no way of knowing what caused the exception), I decided to try to figure out the origin of this exception and to look for more accurate and detailed information.What I found is that the exception occurs on the first line of LLFileUtils.streamWriterDim value2 As LLValue = Me.fConnection.fOutArgs.toValue("FileAttributes")In fact, the real problem is that nowhere in the functions flow is there a validation done to know if the request succeeded before trying to access the properties. Moreover, by looking at the fOutArgs LLValue, we can see that everything was prepared to give the information correctly but this missing validation prevents it from occuring.The chain of functions is:LLConnect.execute(LLConnect)LLConnect.executeHTTP(LLConnect) / LLConnect.executeTraditional(LLConnect)LLConnect.receiveFileDownload()LLConnect.fFileUtils.streamWriter(LLConnect.fOutFile, LLConnect.fBufferedInput)Dim value2 As LLValue = Me.fConnection.fOutArgs.toValue("FileAttributes")All this occurs right after calling LLConnect.crackInputStream(LLConnect).At that point, the status of the request is known and stored in LLConnect.fOutArgs._status as an integer.An easy solution would be to modify LLConnect.receiveFileDownload and add a validation similar toIf (me.fOutArgs.toInteger("_Status") != 0){ [Do actual LLConnect.receiveFileDownload processing]}/*else{ [Do nothing since everything is already there to generate a standard LAPI error}*/It may be important to note that we can't call me.getStatus at this stage since it uses LLConnect.fStatus and that it gets populated only when calling LLConnect.unMarshall which is the following instruction that won't be reached because an exception was already thrown.As you may already be thinking, this would have been too easy (for us at least but for OT, it should be simple to release a patch quickly). The problem is that LLConnect.receiveFileDownload is private and so can't be overriden.The solution then relies on handling the useless exception. In fact, we may consider ourselves lucky that CrackInputStream was already called. In fact, its role is to retrieve every variable sent back from the server and one of them is _Status. This means that even though we can't call GetStatus because fStatus wasn't populated, we're still able to use fOutArgs.toInteger("_Status") (which makes me wonder why GetStatus isn't simply retrieving value from fOutArgs... maybe a perfomance hit because of the toInteger call).So here is a little workaround until OT finds the time to add the real clean one line solution.dim status as integertry dim DocAPI as New LAPI_DOCUMENTS(MySession) status = DocAPI.fetchVersion(VolumeID, NodeID, VersionNumber, New System.IO.BinaryWriter(oMemStream))catch ex as com.opentext.api.LLUnknownFieldException try MySession.unmarshall() MySession.getStatus() catch ex2 as exception throw ex end tryend try[Do Standard status handling]
Find more posts tagged with
Comments
Louis_Routhier
A bug has been opened under LPO-109. If you think this may be of interest for you, maybe you could add your name to it.