loadUrl and non-existent link?


In my app i am using loadUrl to load in an xml file from a dropbox folder. When the file in dropbox is deleted my app crashes.

ci::DataSourceRef dataSourceRef = ci::loadUrl(strFullPath.c_str());
if (!dataSourceRef) return;
if (!dataSourceRef->getBuffer()) return;
if (dataSourceRef->getBuffer()->getSize() == 0) return;

doc = ci::XmlTree(dataSourceRef);

It seems to load something in (not sure what! i have deleted the file in dropbox!!) and try to parse it, causing a crash in doc.parserapidxml::parse_doctype_node( bufString.get() );

void XmlTree::loadFromDataSource( DataSourceRef dataSource, XmlTree *result, const XmlTree::ParseOptions &parseOptions )
	auto buf = dataSource->getBuffer();
	size_t dataSize = buf->getSize();
	unique_ptr<char[]> bufString( new char[dataSize+1] );
	memcpy( bufString.get(), buf->getData(), buf->getSize() );
	bufString.get()[dataSize] = 0;
	rapidxml::xml_document<> doc;    // character type defaults to char
	if( parseOptions.getParseComments() )
		doc.parse<rapidxml::parse_comment_nodes | rapidxml::parse_doctype_node>( bufString.get() );
		**doc.parse<rapidxml::parse_doctype_node>( bufString.get() );**
	parseItem( doc, NULL, result, parseOptions );**
	result->setNodeType( NODE_DOCUMENT ); // call this after parse - constructor replaces it

If the xml file is deleted i would like my app to handle this gracefully instead of crashing as it does now.
Is there a way for loadUrl to detect the file no longer exists and to throw its exception or tell me before it crashes?

Can you not wrap the constructor to XmlTree in a try..catch?

Failing that, my understanding is that DataSources are lazily evaluated, so simply calling loadUrl doesn’t actually do anything. loadString ( loadUrl ( ... ) ), for example, will trigger the url to be fetched and after that is when you can start checking the data. It will also cause a cinder::UrlLoadExc to be thrown in the case of a dead URL

Or, as i said, wrap the whole thing in a big, dumb, try/catch and go make a sandwich. :slight_smile:

1 Like

simple is best. big try/catch it is, works great now :slight_smile:
thanks for the help