tags:

views:

49

answers:

1

I've written some fairly extensive Perl modules and scripts using the Perl bindings SVN::Client etc. Since the calls to SVN::Client are all deep in a module, I have overridden the default error handling.

So far I have done so by setting

$SVN::Error::handler = undef;

as described in the docs, but this makes the individual calls a bit messy because you have to remember to make each call to SVN::Client in list context and test the first value for errors.

I would like to switch to using an error handler I would write; but $SVN::Error::handler is global, so I can't see any way that my callback can determine where the error came from, and what object to set an error code in.

I wondered if I could use a pool for this purpose: so far I have ignored pools as irrelevant to working in Perl, but if I call a SVN::Client method with a pool I have created, will any SVN::Error object be created in the same pool?

Has anybody any knowledge or experience which bears on this?

+1  A: 

OK, I'm going to assume the issue is that (a) you want to set a flag in some object when an error occurs, and then check the flag later at the end of all operations, and (b) that your error handler (in a global variable) needs some way to know which object to touch. You can achieve this using a closure, something like the following:

#
# This part is the library that implements error handling a bit like
# SVN::Client
#
sub default_error_handler {
  croak "An error occurred: $_[0]";
}

our $global_error_handler = \&default_error_handler;

sub library_function_that_might_fail {
  &$global_error_handler("Guess what - it failed!");
}

#
# This part is the function that wants to detect an error
#
sub do_lots_of_stuff {
  my $error = undef; # No errors so far!

  local($global_error_handler) = sub { $error = $_[0]; };

  library_function_that_might_fail();
  library_function_that_might_fail();
  library_function_that_might_fail();

  if ($error) {
    print "There was an error: $error\n";
  }
}


#
# Main program
#
do_lots_of_stuff();

The key is that when, in do_lots_of_stuff(), we set the error handler to an anonymous sub, that sub continues to have access to the local variables of the function that created it - so it can modify $error to signal that an error occurred.

psmears
Thanks. I asked the question quite a while ago, and have moved on somewhat; but when I go back to this project I'll consider this suggestion. Its sounds like just what I wanted.
Colin Fine