Wah, interesting; test.cpp on my machine ends up in the catch for SAXError&.
/me digs back into research. -Patrick On Tue, May 18, 2010 at 11:23 AM, Ben Griffin <[email protected]> wrote: > It behaves exactly the same - dropping out at 'unknown exception' > >> I'm looking into it as we speak, but as I do, would you mind running >> the test.cpp form my first post, to see which of the catch() sections >> triggers for you? I'm just really curious. Here's the source again for >> easy reference: >> >> http://www.rutski89.com/static/xerces-test.cpp >> >> Thanks again for the help thus far, >> -Patrick >> >> On Tue, May 18, 2010 at 10:36 AM, Ben Griffin <[email protected]> wrote: >>> Well now, as I said, I'm not an expert on either xercesc or on exceptions >>> but what I see is >>> This is what is throwing the error to the handler. >>> -------------------------------------------------- >>> void XercesDOMParser::error( const unsigned int >>> , const XMLCh* const >>> , const XMLErrorReporter::ErrTypes errType >>> , const XMLCh* const errorText >>> , const XMLCh* const systemId >>> , const XMLCh* const publicId >>> , const XMLFileLoc lineNum >>> , const XMLFileLoc colNum) >>> { >>> SAXParseException toThrow = SAXParseException >>> ( >>> errorText >>> , publicId >>> , systemId >>> , lineNum >>> , colNum >>> , getMemoryManager() >>> ); >>> >>> // >>> // If there is an error handler registered, call it, otherwise ignore >>> // all but the fatal errors. >>> // >>> if (!fErrorHandler) >>> { >>> if (errType == XMLErrorReporter::ErrType_Fatal) >>> throw toThrow; >>> return; >>> } >>> >>> if (errType == XMLErrorReporter::ErrType_Warning) >>> fErrorHandler->warning(toThrow); >>> else if (errType >= XMLErrorReporter::ErrType_Fatal) >>> fErrorHandler->fatalError(toThrow); >>> else >>> fErrorHandler->error(toThrow); >>> } >>> -------------------------------------------------- >>> As I see it, the 'toThrow' exception is going to go out of scope as soon as >>> your error reporter returns - but then throwing instantiated exceptions >>> this way is one reason why i don't know or understand them - maybe it's >>> fine. >>> >>> But my =guess= would be that you want to clone the exception - or treat it >>> as a temporary messenger object - which would indicate why your re-throw is >>> failing - as the memory is being recovered as the exception is passed out >>> of scope again. >>> >>> What do you think? >>> >>> >>> On 18 May 2010, at 15:22, Patrick M. Rutkowski wrote: >>> >>>> Oh! Oh! >>>> >>>> So it does throw to the catch(...), with the "unknown error"! >>>> >>>> That's exactly why it's broken! >>>> >>>> What's being thrown is a SAXParserException, which SHOULD be caught by >>>> the catch(SAXException& e)! not catch(...)! >>>> >>>> The weird thing is that when I run the test.cpp, which I originally >>>> posted, it does indeed get caught by the right hander, but then when I >>>> later run the same code in my actual project (which was the 2nd source >>>> listing in the original posted) it gets caught by a different handler! >>>> (the ... hander, which is wrong). >>>> >>>> I wonder if you'll see the point I'm trying to make there :-) >>>> -Patrick >>>> >>>> P.S. >>>> I haven't even read the rest of your message yet, I just really felt >>>> like responding to the first two line independently. >>>> I'll read the rest now though. >>>> >>>> On Tue, May 18, 2010 at 10:01 AM, Ben Griffin <[email protected]> wrote: >>>>> Yes it throws. >>>>> It is handled by your fatalError which then re-throws it to .. your >>>>> "unknown error" catch. >>>>> I don't know much about exception handling- in fact I avoid using them >>>>> when I can. >>>>> >>>>> Instead, I install a DOMErrorHandler and then gather messages until after >>>>> the parse. But that's me. >>>>> I use a single DOMLSParser which lasts for the duration of the process, >>>>> and then I let it manage the documents as it likes. >>>>> So my normal approach is to use my own 'loadDocument' method which deals >>>>> with the parsing and returns a DOMDocument, or a NULL >>>>> Here is a simple example, which actually comes from a bug report. >>>>> >>>>> #include <iostream> >>>>> #include <sstream> >>>>> #include <xercesc/dom/DOM.hpp> >>>>> >>>>> using namespace xercesc; >>>>> using namespace std; >>>>> >>>>> class myErrorHandler : public DOMErrorHandler { >>>>> ostringstream errors; >>>>> public: >>>>> bool handleError(const xercesc::DOMError& domError) { >>>>> char* msg = XMLString::transcode(domError.getMessage()); >>>>> errors << "[" << msg << "]"; >>>>> XMLString::release(&msg); >>>>> return true; >>>>> } >>>>> void errs(string& result) { >>>>> result = errors.str(); >>>>> errors.str(""); >>>>> } >>>>> myErrorHandler() : DOMErrorHandler() {} >>>>> }; >>>>> >>>>> int main(int argc, char *argv[]) { >>>>> const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull}; >>>>> XMLPlatformUtils::Initialize(); >>>>> myErrorHandler* errorHandler = new myErrorHandler(); >>>>> DOMImplementation* impl >>>>> (DOMImplementationRegistry::getDOMImplementation (ls_id)); >>>>> DOMLSParser* xmlParser = impl->createLSParser >>>>> (DOMImplementationLS::MODE_SYNCHRONOUS,NULL); >>>>> DOMConfiguration* conf (xmlParser->getDomConfig ()); >>>>> conf->setParameter(XMLUni::fgDOMErrorHandler,errorHandler); >>>>> conf->setParameter(XMLUni::fgXercesCacheGrammarFromParse,true); >>>>> conf->setParameter(XMLUni::fgXercesUseCachedGrammarInParse,true); >>>>> conf->setParameter(XMLUni::fgXercesSchema,true); >>>>> conf->setParameter(XMLUni::fgXercesIgnoreCachedDTD,false); >>>>> conf->setParameter(XMLUni::fgDOMValidate,true); >>>>> DOMDocument *foo = NULL; >>>>> xmlParser->loadGrammar("foo.xsd",Grammar::SchemaGrammarType,true); >>>>> foo = xmlParser->parseURI("foo.xml"); >>>>> string err; >>>>> errorHandler->errs(err); >>>>> cout << "Errors for foo.xml:" << err << endl; >>>>> XMLPlatformUtils::Terminate(); >>>>> return 0; >>>>> } >>>>> >>>>> Adding memory inputsource is a bit more tricky - but I do it something >>>>> like this: >>>>> >>>>> const XMLCh *mem = {chLatin_M, chLatin_E, chLatin_M, chNull}; >>>>> std::string xmlfile = "<? xml version="1.0" ?><bla bla bla />" ; >>>>> DOMDocument *foo = NULL; >>>>> DOMLSInput *input = ((DOMImplementationLS*)impl)->createLSInput(); >>>>> XMLByte *xmlraw = (XMLByte*)(xmlfile.c_str()); >>>>> MemBufInputSource *mbis = new >>>>> MemBufInputSource(xmlraw,xmlfile.size(),mem); >>>>> mbis->setCopyBufToStream(false); >>>>> input->setByteStream(mbis); >>>>> input->setEncoding(XMLUni::fgUTF8EncodingString); >>>>> try { >>>>> foo = parser->parse(input); >>>>> } catch (...); //deal with parser throws here! >>>>> input->release(); >>>>> >>>>> I cannot say that eny of this is the right way to do things, but maybe >>>>> it's of some use to you? >>>>> Lots of people use SAX instead of DOM, which depends upon your purpose of >>>>> course. >>>>> >>>>> Not really sure that any of this helps. >>>>> I am really STILL LEARNING xercesc after five years. Just ask Alberto how >>>>> annoying I can be at times :D >>>>> >>>>>> Well, yeah, I am just learning the basics :-) >>>>>> >>>>>> But I figured that deleting the XercesDOMParser and returning the >>>>>> DOMDocument would be wrong, because the XercesDOMParser owns the >>>>>> DOMDocument, no? >>>>>> >>>>>> -Patrick >>>>>> >>>>>> P.S. >>>>>> Did running my "broken" code on your machine trigger the catch(...) or >>>>>> the catch(const SAXException& e)? >>>>>> >>>>>> On May 18, 2010, at 7:08 AM, Ben Griffin wrote: >>>>>> >>>>>>> I had a look at your 'broken' source. >>>>>>> There was no main function, so I added one in as follows: >>>>>>> >>>>>>> int main() { >>>>>>> XMLPlatformUtils::Initialize(); >>>>>>> XercesDOMParser* parser = ParseXML("input"); >>>>>>> return 0; >>>>>>> } >>>>>>> >>>>>>> I commented out the QK:: push stuff, because it's not part of the >>>>>>> library (that I know of). >>>>>>> >>>>>>> I added >>>>>>> #include <xercesc/parsers/XercesDOMParser.hpp> >>>>>>> >>>>>>> I don't have / don't use util.hpp so I added >>>>>>> namespace { >>>>>>> typedef std::basic_string<XMLCh> XercesString; >>>>>>> } >>>>>>> >>>>>>> Regardless, I have sent you the source code directly. >>>>>>> It compiles and runs. >>>>>>> >>>>>>> I don't really know why you would want to return the parser having >>>>>>> parsed a file. Normally one wants the document from the parse. >>>>>>> Maybe you are just getting the basics up first...! >>>>>>> >>>>>>> >>>>>>> On 18 May 2010, at 12:01, Patrick Rutkowski wrote: >>>>>>> >>>>>>>> If any of you Xerces-C devs are up for it, I would be willing to go as >>>>>>>> far as doing a screen-sharing session to debug this, since it seems to >>>>>>>> be impossible to reproduce. I have my version of xerces already built >>>>>>>> with -g -O0 even. >>>>>>>> >>>>>>>> Of course, that might amount to you helping me find a silly big in my >>>>>>>> code somewhere, free of charge, which might seem unfair. Then again, >>>>>>>> maybe it really is an obscure bug in Xerces, which would make it worth >>>>>>>> it. >>>>>>>> >>>>>>>> I dunno, I just don't know what to do anymore :-/ >>>>>>>> >>>>>>>> -Patrick >>>>>>>> >>>>>>>> On May 18, 2010, at 2:47 AM, Vitaly Prapirny wrote: >>>>>>>> >>>>>>>>> Patrick Rutkowski wrote: >>>>>>>>>> I have verified with test prints and gdb that fatalError() >>>>>>>>>> in ThrowErrorHandler is indeed triggered like it's supposed >>>>>>>>>> to be, so we're good so far. >>>>>>>>> >>>>>>>>> So the parser->setErrorHandler() is not broken actually, your subject >>>>>>>>> line misleads. I could assume your toolchain or project is >>>>>>>>> somewhat broken. If you could prepare a minimal self-contained test >>>>>>>>> case >>>>>>>>> it would be very helpfull to someone who wished to look at it. >>>>>>>>> >>>>>>>>> Good luck! >>>>>>>>> Vitaly >>>>>>>> >>>>>>> >>>>>> >>>>> >>>>> >>> >>> > >
