Error Handling
**************

If an X object method generates an error, it will be handled in one of two different ways depending on the kind of method.  Errors are represented by X error objects in the Xlib.

If the method does not return data, the error will most likely be detected after the method has returned.  All methods which does not return data has a parameter called onerror, which can be used to provide a error handler for errors generated by this method.

The error handler is called with to arguments: the error object and the low-level request object.  The error must not do call any X object methods.  If that is necessary, the error handler must store the error away for later retrieval.  The class error.CatchError is provided for this purpose.

If no error handler is given when calling a method which generates an error, the error will be passed to the default error handler.  If no default error handler is specified, the error is simply printed on sys.stderr.

If the method does return data, the error will make it impossible for it to return any valid data.  An exception is raised with the error object as the exception value.  It is not passed to any error handlers.

X Error Classes
===============

X errors are structured in the following class hierarchy:

     Exception
      \_ error.XError
          \_ error.BadRequest
          \_ error.BadValue
          \_ error.BadAtom
          \_ error.BadMatch
          \_ error.BadAccess
          \_ error.BadAlloc
          \_ error.BadName
          \_ error.BadLength
          \_ error.BadImplementation
          \_ error.XResourceError
              \_ error.BadWindow
              \_ error.BadPixmap
              \_ error.BadCursor
              \_ error.BadFont
              \_ error.BadDrawable
              \_ error.BadColor
              \_ error.BadGC
              \_ error.BadIDChoice

All error objects has the following attributes:

code

     The numeric error code

sequence_number

     The sequence number of the failed request

resource_id

     The bad resource id.  For all the error.XResourceError this is a X resource object.  For the other errors it is an integer, which for some errors might have no meaning

major_opcode

     The major opcode for the failed request

minor_opcode

     The minor opcode for the failed request.  This will be zero for all base X11R6 request, but will be interesting for extension requests

CatchError
==========

error.CatchError is an object which can be used as an error handler.  It collects an error matching any of the specified types, which can be retrieved later.  If several errors occures, only the last is remembered.

 -- Class: CatchError ( *errors )

     Create a new error handler object.  Initialize by providing all error classes you are interested in as arguments.  If no error classes are provided at all, this means that all errors will be considered.

Pass the error.CatchError object as the onerror parameter to X object methods.  If these methods generated any errors matching the ones specified, it can be retrieved with the following functions:

 -- Method on CatchError: get_error ( )

     Return the last error object caught, or None if no matching errors has occured.

 -- Method on CatchError: get_request ( )

     Return the request object for the last error caught, or None if no matching errors has occured.

error.CatchError objects can be reused:

 -- Method on CatchError: reset ( )

     Forget any caught error.

Since the X protocol is mostly asynchronous any error we're watching for might not have been recieved when we call get_error.  To make sure that the request has been processed by the server and any error generated has been received by the Xlib, we must synchronize with the server.

An example of using error.CatchError:

     # Resize and the foo window
     # If it has been destroyed since we looked at it the last time,
     # reset variable foo to None

     # Create a error handler for BadWindow errors
     ec = error.CatchError(error.BadWindow)

     # Perform the operation
     foo.configure(width = 100, height = 200, onerror = ec)

     # Sync communication with server
     display.sync()

     # And check if there was any error
     if ec.get_error():
         foo = None