Hi Paul,

Before 1.0 I think there is one item that needs a serious overhaul. Right now the default error handler is VERBOSE_HANDLER which just writes out error messages to STDERR. This makes it difficult to trap errors since I don't think it's always clear from the return value of method what type of error was encountered.

Ah, thanks for reminding me of that. One of the things I forgot to mention is that error handling has been refactored a lot. There are a number of differences in the 0.9.x releases:

* The bindings now use libxml's "structured" error handler functionality

* This allows the use of XML::Error objects which inherit from Ruby's StandardError.

* These error objects are now passed to error handlers (both the Verbose and Quiet handlers).

* When something goes wrong, the bindings try to raise instances of XML::Error.

* The XML::Error object specifies the type of error (Error#code) plus a bunch of other information.

Having said all that, libxml error handling is still tricky because of the way it works (this is the way the C library works, not the bindings):

1.  Perform some operation, say document.find('some invalid xpath')
2. libxml notes the error, and calls any registered error handlers (for example the verbose or quit error handlers)
3.  It then sets xmlLastError
4. The original method call then returns with, or without, some indication that an error happened (for example, -1 is passed back) 5. The bindings check for an error return code, and if there is one, raise an exception:

rxml_raise(xmlLastError);

This sequence works a fair amount of time, but not always.

I propose using either
some type of exception hierarchy with specific exceptions as appropriate (e.g. WellFormednessError, DTDValidationError, etc.).

I don't think its worth it - libxml defines almost 1,000 error codes. To get at the information, check XML::Error#code and XML::Error#domain

 If this is not
feasible on a short time scale I think at a minimum the current error handling should be refactored to stash the current error message in the Error object on Parser.

libxml already maintains a global object called xmlLastError, which the bindings make use.

 Methods could then raise exceptions for error
(or in the interim, return nil) and the caller could get the message back.

Yes, they do now (that was part of the big refactoring). However, I'm sure there are places in the code I missed that still need to be updated.

I'd like to see what your thoughts are on this, I'm happy to provide the first pass at a patch that implements this behavior. Error handling right now is a major obstacle for me.

Sure. I'd say find out what methods are causing you problems, then update them to raise errors when something goes wrong. You can do that like this:

rxml_raise(xmlLastError);

Note it won't always work, because xmlLastError is not always set by libxml.

Charlie

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

_______________________________________________
libxml-devel mailing list
libxml-devel@rubyforge.org
http://rubyforge.org/mailman/listinfo/libxml-devel

Reply via email to