Tuesday, 2 July 2013

Daft bug with objectSave() and XML

G'day:
Ever have one of those days in which you spend most of your time fighting with ColdFusion, rather than getting your work done? Well if so, you're familiar with the last week of my life. And it continues...

Here's some code which demonstrates successfully saving/loading an array with objectSave() and objectLoad():

months = ["Kohi-tātea","Hui-tanguru","Poutū-te-rangi","Paenga-whāwhā","Haratua","Pipiri","Hōngongoi","Here-turi-kōkā","Mahuru","Whiringa-ā-nuku","Whiringa-ā-rangi","Hakihea"];
savedObject = objectSave(months);
loadedObject = objectLoad(savedObject);
writeDump(var=loadedObject, label="loadedObject");

Result:
loadedObject - array
1Kohi-tātea
2Hui-tanguru
3Poutū-te-rangi
4Paenga-whāwhā
5Haratua
6Pipiri
7Hōngongoi
8Here-turi-kōkā
9Mahuru
10Whiringa-ā-nuku
11Whiringa-ā-rangi
12Hakihea

Cool. Now here's some code doing the same with some XML:

colours = xmlParse('<whero><kowhai kakariki="maota" /></whero>');
writeDump(var=colours, label="colours");
try {
    savedObject = objectSave(colours);
    loadedObject = objectLoad(savedObject);
    writeDump(var=loadedObject, label="loadedObject");
}
catch (any e){
    writeDump([e.message,e.detail,e.type, e.tagcontext[1].raw_trace]);
}

Result:

colours - xml document [short version]
whero
XmlText
kowhai
XmlText
XmlAttributes
colours - struct
kakarikimaota
array
1Error occurred while performing ObjectSave: Object passed is not serializable java.io.NotSerializableException: coldfusion.xml.XmlNodeList
2[empty string]
3Application
4at cfobjectSaveVsXml2ecfm655459134.runPage(D:\websites\www.scribble.local\cf\cfml\functions\conversion\objectSave\tostring\objectSaveVsXml.cfm:11)

This bites. What pisses me off about this is because XML, at its core, is text. So don't give me "NotSerializableException". Yeah, I get that in CFML XML is stored in an object (of type coldfusion.xml.XmlNodeList), but actual XML is text. And XmlNodeList implements a toString() method which... well... does what it says on the tin, and CFML itself provides a toString() function to do the same thing. So I dunno in which world objectSave() doesn't think a CFML XML object isn't serialisable.

But at least one gets an error when things go pear-shaped here.

Check this variation out, which differs in that I put the XML in a struct...

colourWrapper = {
    colour    = "kikorangi",
    colours = xmlParse('<whero><kowhai kakariki="maota" /></whero>')
};
writeDump(var=colourWrapper, label="colourWrapper");


savedObject = objectSave(colourWrapper);
loadedObject = objectLoad(savedObject);
writeDump(var=loadedObject, label="loadedObject");

And this yields:

colourWrapper - struct
COLOURkikorangi
COLOURS
colourWrapper - xml document [short version]
whero
XmlText
kowhai
XmlText
XmlAttributes
colourWrapper - struct
kakarikimaota
loadedObject - struct
COLOURkikorangi

OK... so where's the XML gone? I fully expected this to error (for the same reason as above), but CF seems to have taken it upon itself to simply not do half the work I asked it to, and then gone "ta-dah!" as if it's done the correct thing.

Not being able to do something as fundamental as knowing how to serialise XML is one thing. But simply ignoring this and providing bad data is at least as bad, if not worse.

If something goes wrong... tell the calling code. Don't just sweep it under the carpet.

Bugs raised:
  1. objectSave() errors with XML (3588558) 
  2. Incorrectly functioning objectSave() does not report errror (3588559) 
Railo, incidentally... works fine.

I'd soooo like to have an afternoon of not fighting with ColdFusion bugs, if that'd be OK? I might go back and just type in <cfset foo="bar"> hundreds of times. At least that's likely to work.

--
Adam