%FromJSON() failing with content larger than 32kb
We have a business service that extends
This service polls for json files in a folder.
Method signature is like this:
And inside that method it tries to read the content like this:
if ($$$ISERR(tStatus)) quit
set tJSON = {}.%FromJSON(tData)
I added some trace calls before and after lines and noticed it's always that last line that fails if content is larger than 32kb.
Any workaround for this? Or is this wrong way to do it to begin with and something else should be there instead?
Our Ensemble version is 2016.2.1
The ReadLine() method of %FileCharacterStream defaults to a length of 32K.
Have you tried simply passing the stream object, pInput, as the argument to %FromJSON()?
Wow, that actually works! Thanks so much, Jeffrey!
This isn't originally my code so I don't know why that
set tData = pInput.ReadLine(,.tStatus, .tEOL)
part is there and tdata is used as argument instead of pinput but probably for some reason? So even thou I'm happy your suggestion actually works, I'm also worried if that change breaks something else. But on the other hand, it did not on my initial tests anyway. I get exactly the same output with those json files that worked earlier but now also larger files work fine. Hmmm...
Exception still can contain some useful info, so:
#dim tSC As %Status = $$$OK ... try { set tJSON = {}.%FromJSON(pInput) } Catch ex { do ex.Log() set tempSC = $$$ERROR($$$GeneralError,"Badly formed JSON") set tSC = $$$ADDSC(tempSC, ex.AsStatus()) } quit tSC
Thank you @Eduard Lebedyuk! Good to know
The only reason I can think of doing it the way it was done is that there was no expectation by the original author of the code that the JSON object would be larger than 32KB. It's also possible that he/she was unfamiliar with the types of objects that %FromJSON() works with and always assumed it was a simple string ... which is what the ReadLine() method returns.
Here's the documentation for for the %FromJSON() method.
I'd also recommend to remove or change this line:
if ($$$ISERR(tStatus)) quit
because your method signature has a promise to return a %Status:
Method OnProcessInput(pInput As %FileCharacterStream, pOutput As %RegisteredObject) As %Statu
however above mentioned line quits nothing.
You can rewrite it like this (to return status):
if $$$ISERR(tStatus) quit tStatus
or my personal preference like this using postconditionals:
quit:$$$ISERR(tStatus) tStatus
Well in this exact case you need to remove the line altogether because you no longer get status for ReadLine, but it's just some food for thought.
As @Eduard Lebedyuk pointed out, the method should return a status as indicated by its signature, so at the very minimum you should have a "Return $$$OK" at the end of the method.
That said, %FromJSON() throws an exception when it fails, and the generic error you'll get in the Event Log won't tell you (or your support team) much. You may want to wrap a try/catch around the call to %FromJSON() so that you can return a status that provides a little more insight:
... Try { set tJSON = {}.%FromJSON(pInput) } Catch { Return $$$ERROR($$$GeneralError,"Badly formed JSON") } ... Return $$$OK }