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
>>>>> 
>>>> 
>>> 
>> 
>> 

Reply via email to