Skip to Content.
Sympa Menu

devel - Re: [sympa-developpers] Using exception

Subject: Developers of Sympa

List archive

Chronological Thread  
  • From: IKEDA Soji <address@concealed>
  • To: address@concealed
  • Subject: Re: [sympa-developpers] Using exception
  • Date: Wed, 16 Oct 2013 12:49:53 +0900

Hi all,

On Mon, 14 Oct 2013 17:16:27 +0900
IKEDA Soji <address@concealed> wrote:

> - Use of $@ without dying: Several module functions such as
> MIME::EncWords::decode_mime_words() sets $@ without dying
> (N.B. this feature is not my original but derived from MIME::Words).
>
> Soution: There seems nothing to do by our module.

It is not desirable that Sympa stops due to such "forged" exception
(How much Sympa usually receives messages with broken header-
encodings!). So I revised POD.
And I added "COMMON USAGE MISTAKES" section on my concern about
"finally" problem.

I wrote test cases, too.

May I write the code? It will takes a few days, I'll bet.
Or, will we throw away this idea? I don't mind if such decision
will be taken.

Cheers,

--- Soji

--
株式会社 コンバージョン セキュリティ&OSSソリューション部 池田荘児
〒231-0004 神奈川県横浜市中区元浜町3-21-2 ヘリオス関内ビル7F
e-mail address@concealed TEL 045-640-3550
http://www.conversion.co.jp/

=encoding us-ascii

=head1 NAME

Sympa::Exception - Generating and processing exceptions

=head1 SYNOPSIS

Defining exceptions:

    use Sympa::Exception
        'Sympa::Exception::Foo' => { description => 'Foo occurred' },
        'Sympa::Exception::Bar' => { description => 'Bar emerged' },
        ;

Throwing an exception:

    Sympa::Exception::Foo->throw;

Catching exceptions:

    eval {
        ...
        # Any code possibly throws exceptions
        ...
    };
    if (my $e = Sympa::Exception->catch) {
        cleanup();   # You may have to write this.
        if ( $e->isa('Sympa::Exception::Foo') ) {
            ...
        } elsif ( $e->isa('Sympa::Exception::Bar') ) {
            ...
        } else {
            $e->throw;
        }
    }

=head1 DESCRIPTION

L<Sympa::Exception> provides feature to generate and process exceptions.

Exceptions are captured by C<eval { }> block.
catch() method consumes them.

Uncaught exceptions must be re-thrown.

=head2 Method

=over

=item Sympa::Exception->catch

I<Class method>.
Consumes exception, if it had been thrown.
Returns caught exception object or false value.

If exception does not belong to the class descended from
L<Sympa::Exception::Base>, uncatchable exception (see below) will be thrown.

I<Note>:
Some modules (e.g. L<MIME::EncWords>, L<Text::Balanced>) may set
C<$EVAL_ERROR> (C<$@>) without throwing exception.
In such cases catch() outputs value of C<$@> using warn().

=back

=head2 Methods of exception objects

=over

=item E<quot>$exceptionE<quot>

I<Overridden operator>.
Returns error message and traceback.

By this function, exceptions never caught will output traceback to STDERR.

=item $exception->isa ( CLASS_NAME )

I<Instance method>.
Tests type of exception.

=item Sympa::Exception::I<Subclass>->throw ( ... )

I<Class method>.
Throws an exception.
This is equivalent to C<die Sympa::Exception::I<Subclass>-E<gt>new(...)>.

Note that the exceptions you don't wish to catch I<must> be thrown again.

=back

=head2 Basic exception classes

=over

=item Sympa::Exception::Base

Base class of all exceptions on Sympa.
This class I<should not> be used directly;
define appropriate subclasses and use them (see below).

=item Sympa::Exception::BuiltIn

The exception thrown by built-in functions.
To find out how to use this exception in details,
see L<Sympa::Exception::AutoDie>.

=item L<Sympa::Exception::Fatal>

Uncatchable exception.
This may be thrown when any programs of Sympa must terminate immediately.

=item L<Sympa::Exception::Internal>

The exception thrown from internals of Perl or external modules
by die(), croak() and so on with simple scalar argument.

=back

=head2 How to define new exceptions

There is an easy way to define arbitorary subclasses of
L<Sympa::Exception::Base>:

  use Sympa::Exception
      'Sympa::Exception::Foo'      => { description => 'Foo occurred' },
      'Sympa::Exception::Foo::Bar' => { description => 'Bar emerged',
                                        isa => 'Sympa::Exception::Foo' },
      ...
      ;

You may also define subclass by orthodox manner:

  package Sympa::Exception::Foo;
  use strict;
  use warnings;
  use base qw(Sympa::Exception::Base);
  ...
 
Anyway, it is I<recommended> that the names of new exception classes have
the prefix C<Sympa::>, for example C<Sympa::Exception::List>,
C<Sympa::List::Exception>.

=head1 COMMON USAGE MISTAKES

In the code

    eval {
        lock_resources();
        process_probably_throws_exception();
        unlock_resources();
    };
    if ( my $e = Sympa::Exception->catch ) {
        # process exceptions...
    }

when an exception was thrown, resources will keep locked.

To avoid such unhappiness,
make sure that cleanup will be done at the beginning of "catch" block:

    ...
    
    if ( my $e = Sympa::Exception->catch ) {
        unlock_resources();
        # peocess exceptions...
    }

=head1 SEE ALSO

L<Sympa::Exception::AutoDie>.

=head1 AUTHORS

Sympa developers and contributors.

=cut

Attachment: catch.t
Description: Troff document




Archive powered by MHonArc 2.6.19+.

Top of Page