On Wed, 2005-08-03 at 18:46 +0200, Dirk Meyer wrote:
> How? I register to waht kind of exception? E.g. a handler should know
> about all parts raising an exception and inner kaa parts don't know
> about freevo exceptions.

You can connect to the "exception" signal of a notifier object (i.e.
anything derived from NotifierCallback, like Timer, SocketDispatcher).
Any exception that occurs when the callback is called will be passed as
an argument to callbacks connected to the exception signal.  If nothing
is connected to the exception signal, then the exception propagates back
up to the notifier loop as it normally would.

> Yes, but I guess that should be inside a try/except. So 
> 
> | try:
> |   # maybe this won't work
> |   open()
> | except (IOError, OSError):
> |   do_something_about_it

Ok, let's say we have a function do_foo_thing(filename) which opens
filename and does a foo on it.

        def do_foo_thing(filename):
           fp = open(filename, "w")
           fp.seek(1000)
           fp.write("foo")

Now, we could wrap each of those file calls in try/except clauses,
because each of them could potentially raise an IOError.  But it's
useful to let the caller of do_foo_thing() handle such exceptions:

        try:
           do_foo_thing(somefile)
        except IOError:
           print "Foo thing failed"
        
Now let's say we want to do_foo_thing() in 2 seconds.  We use a timer.

   OneShotTimer(do_foo_thing, somefile).start(2)

But what happens if do_foo_thing() raises an IOError?  We can't handle
it like we did above, because do_foo_thing() gets called by the
notifier.  We need to handle an exception that could be raised by
do_foo_thing() to do something.  If that something was the same thing
all the time, then I suppose it could be handled right in
do_foo_thing().  But the point of setting an error condition is to let
the caller handle the error in a custom way.  It's true that
do_foo_thing() could handle the exception and return some error code
that reflects the nature of the exception, but then we might as well be
using C -- we throw away the whole benefit of exceptions.  (And even in
that case, we'd need some way to handle the return code returned by
do_foo_thing().)

So now we can do this:

        def handle_do_foo_thing_exception(e):
           print "Foo thing failed"
        
        timer = OneShotTimer(do_foo_thing, somefile)
        timer.signals["exception"].connect(handle_do_foo_thing_exception)
        timer.start(2)
        
This implements the exception handling of do_foo_thing() from above,
only it does so asynchronously.  We can use the same approach for a
thread:

        thread = notifier.Thread(do_foo_thing, somefile)
        thread.signals["exception"].connect(handle_do_foo_thing_exception)
        thread.start()
        
Jason.

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to