Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Creating exception classes

by perlbaski (Acolyte)
on Feb 05, 2013 at 01:16 UTC ( #1017037=perlquestion: print w/ replies, xml ) Need Help??
perlbaski has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to create exception class hierarchy. But I think I am not declaring them correctly as I am not able to refer to the exception objects.

use Exception::Class ( 'MyException', 'Commands' => { isa => 'MyException' }, 'Timeout' => { isa => 'Commands', description => 'These exceptions are resulted from running the metrics comm +ands' }, 'DBError' => { isa => 'MyException', description => 'DB returned error' } ); ThrowMyException(); sub ThrowMyException() { eval{MyException::Commands::Timeout->throw(error=>"This is error d +ue to timeout");}; my $err; if($err=Exception::Class->caught('MyException::Commands::Timeo +ut')){ #print Dumper($err); #print "err is of type ".ref($err); die $err->{"description"}.": ".$err->{"error"}; } elsif ( $err = Exception::Class->caught("MetricsException") ) +{ #print Dumper($err); die $err->error; } }

Can somebody see what is wrong with the code?

Comment on Creating exception classes
Download Code
Re: Creating exception classes
by Athanasius (Monsignor) on Feb 05, 2013 at 02:35 UTC

    The problems are not in the declaration, but in sub ThrowMyException. Here is a working version, with changes commented:

    #! perl use strict; use warnings; use Exception::Class ( 'MyException', Commands => { isa => 'MyException', }, Timeout => { isa => 'Commands', description => 'This exception results from running the metric +s commands', }, DBError => { isa => 'MyException', description => 'DB returned error', }, ); ThrowMyException(); print "No error caught\n"; sub ThrowMyException # NO prototype { eval { Timeout->throw # NOT MyException::Commands::Timeo +ut-> ( error => "This error is due to a timeout" ); }; my $err; if ($err = Exception::Class->caught('Timeout')) { die $err->description . # NOT $err->{"description"} ': ' . $err->error; # NOT $err->{"error"} } elsif ($err = Exception::Class->caught('MetricsException')) { die $err->error; } else { $err = Exception::Class->caught(); ref $err ? $err->rethrow : die $err; } }

    Output:

    12:30 >perl 517_SoPW.pl This exception results from running the metrics commands: This error i +s due to a timeout at 517_SoPW.pl line 56. 12:33 >

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Thanks, that worked..I was thinking classes are blessed hashes, so I was trying to access them that way, looks like Exception::Class module creates accessors to access the fields. Am I correct?

        From the source code it appears that Exception::Class inherits from Exception::Class::Base. The documentation for Exception::Class::Base catalogues a number of class and/or object methods, among which are these:

        MyException->description()
        Returns the description for the given Exception::Class::Base subclass. ... This is also an object method.

        $exception->error()
        Returns the error/message associated with the exception.

        So these accessors are, as it were, “built-in” to any class derived from Exception::Class.

        Hope that helps,

        Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Creating exception classes
by 7stud (Deacon) on Feb 05, 2013 at 02:42 UTC
    use strict; use warnings; use 5.012; use Exception::Class ( 'MyException', 'CommandException' => { isa => 'MyException' }, 'TimeoutException' => { isa => 'CommandException', description => 'This exception resulted from running the metrics commands' }, 'DBException' => { isa => 'MyException', description => 'DB returned error' } ); &ThrowMyException(); sub ThrowMyException() { eval{ TimeoutException->throw(error=>"This is error due to timeout +") }; my $err; if ($err = Exception::Class->caught('TimeoutException') ) { #print Dumper($err); #print "err is of type ".ref($err); die $err->description . ": " . $err->error; } elsif ( $err = Exception::Class->caught("MetricsException") ) { #print Dumper($err); die $err->error; } }

    If you see class names like A::B::C, that means the class is named C and it can be found in the directory A/B/. The A::B:: part is a namespace name to prevent name conflicts, but it also indicates the directory structure where the class is located. When you write A::B::C in your program, perl searches all the directories in @INC for a directory named A that has a subdirectory named B, which contains a file called C.pm.

      "When you write A::B::C in your program, perl searches all the directories in @INC for a directory named A that has a subdirectory named B, which contains a file called C.pm."

      No it doesn't. It only does that search if you write use A::B::C, no A::B::C or require A::B::C. Merely mentioning the A::B::C package (for example, to call a constructor) does not force Perl to attempt to load the module.

      The following code does not attempt to load "This/File/Does/No/Exist/On/My/Disk.pm"...

      use strict; use warnings; { package This::File::Does::No::Exist::On::My::Disk; require Math::BigInt; our @ISA = 'Math::BigInt'; } my $number = This::File::Does::No::Exist::On::My::Disk->new(7); print $number * 6, "\n";
      package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1017037]
Approved by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (8)
As of 2014-08-28 06:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (257 votes), past polls