| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package eBay::Exception; | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | ######################################################################### | 
| 4 |  |  |  |  |  |  | # | 
| 5 |  |  |  |  |  |  | # Module: ............... /eBay/API | 
| 6 |  |  |  |  |  |  | # File: ................. Exception.pm | 
| 7 |  |  |  |  |  |  | # Original Author: ...... Bob Bradley | 
| 8 |  |  |  |  |  |  | # | 
| 9 |  |  |  |  |  |  | ######################################################################### | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | =pod | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | =head1 eBay::Exception | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | Ebay exception handling framework. | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | This module provides a framework to users of the eBay::API packages to | 
| 20 |  |  |  |  |  |  | throw, catch and handle severe runtime exceptions gracefully. | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | The eBay::API exceptions inherit the functionality of CPAN modules | 
| 23 |  |  |  |  |  |  | Exceptions::Class and Error, including such informational fields as message, | 
| 24 |  |  |  |  |  |  | error, time, package, etc.  See | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | http://search.cpan.org/~drolsky/Exception-Class-1.23/lib/Exception/Class.pm | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | for a description of Exceptions::Class details. | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | As an end user you have the option of enabling exception handling or | 
| 31 |  |  |  |  |  |  | not.  To enable exceptions you must include eBay::Exception B | 
| 32 |  |  |  |  |  |  | then enable exceptions by calling the Exception class method | 
| 33 |  |  |  |  |  |  | ebay::Exception::enableExceptions(); | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | Exceptions include the following: | 
| 36 |  |  |  |  |  |  |  | 
| 37 |  |  |  |  |  |  | =over 4 | 
| 38 |  |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  | =item * | 
| 40 |  |  |  |  |  |  |  | 
| 41 |  |  |  |  |  |  | B  Base class for all API exceptions. | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | =item * | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | B Exceptions encountered while parsing | 
| 46 |  |  |  |  |  |  | XML content.  This class has an additional informational field: | 
| 47 |  |  |  |  |  |  | I. | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | =item * | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | B Exceptions with using subroutines, | 
| 52 |  |  |  |  |  |  | including the wrong number of parameters, the wrong types of | 
| 53 |  |  |  |  |  |  | parameters, or inconsistent values in parameters.  This exception has | 
| 54 |  |  |  |  |  |  | an additional informational field: I. | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  | =back | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | Not all eBay applications errors may be reported as exceptions.  You | 
| 59 |  |  |  |  |  |  | should always check the individual call responses for other | 
| 60 |  |  |  |  |  |  | application level error information such as failure to list an item | 
| 61 |  |  |  |  |  |  | for a user because that user does not have enough feedback to list an | 
| 62 |  |  |  |  |  |  | item of that type. | 
| 63 |  |  |  |  |  |  |  | 
| 64 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 65 |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  | use eBay::API::XML::Session; | 
| 67 |  |  |  |  |  |  | use eBay::Exception qw(:try); | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | # Uncomment this line to enable the catch block below | 
| 70 |  |  |  |  |  |  | # eBay::Exception::enableExceptions(); | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | try { | 
| 73 |  |  |  |  |  |  | # Example of bad argument to Session constructor | 
| 74 |  |  |  |  |  |  | my $apisession = eBay::API::XML::Session->new('yo'); | 
| 75 |  |  |  |  |  |  | } catch Error with { | 
| 76 |  |  |  |  |  |  | my $error = shift; | 
| 77 |  |  |  |  |  |  | print $error->{argnumber};  # specific to usage errors | 
| 78 |  |  |  |  |  |  | print $error->{package};    # package where error trapped | 
| 79 |  |  |  |  |  |  | print $error->{trace};      # stack trace | 
| 80 |  |  |  |  |  |  | print $error;               # exception type | 
| 81 |  |  |  |  |  |  | print "\n\nCATCHING THE EXCEPTON!\n"; | 
| 82 |  |  |  |  |  |  | } finally { | 
| 83 |  |  |  |  |  |  | #optional cleanup code; | 
| 84 |  |  |  |  |  |  | print "\nIN FINALLY BLOCK.\n"; | 
| 85 |  |  |  |  |  |  | };  # Don't forget the semicolon, this is not a block, but a statement! | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  |  | 
| 88 |  |  |  |  |  |  | =head1 EXTENDING EXCEPTION HANDLING | 
| 89 |  |  |  |  |  |  |  | 
| 90 |  |  |  |  |  |  | It is simple to extend the framework to use it in your own application | 
| 91 |  |  |  |  |  |  | code.  You can define exception classes that inherit from any | 
| 92 |  |  |  |  |  |  | pre-existing Extension::Class and then use and throw these classes in | 
| 93 |  |  |  |  |  |  | your own application code.  If you extend from an eBay exception | 
| 94 |  |  |  |  |  |  | class, then any exceptions you throw will also be logged to the eBay | 
| 95 |  |  |  |  |  |  | logging facility if you throw the exception with the instance method | 
| 96 |  |  |  |  |  |  | ebay_throw().  Whether the exception will actually be thrown, of course, | 
| 97 |  |  |  |  |  |  | depends on whether you have enabled exceptions.  If you just throw() | 
| 98 |  |  |  |  |  |  | the exception, it will always be thrown, and there will be no message | 
| 99 |  |  |  |  |  |  | to the eBay API logging. | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | Example: | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | package myException; | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  | use eBay::Exception; | 
| 106 |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | use base qw(eBay::Exception); | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  | sub foo { | 
| 110 |  |  |  |  |  |  | print "I AM IN FOO.\n"; | 
| 111 |  |  |  |  |  |  | } | 
| 112 |  |  |  |  |  |  |  | 
| 113 |  |  |  |  |  |  | 1; | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | package main; | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | use eBay::Exception qw(:try); | 
| 118 |  |  |  |  |  |  | # Comment out following to disable the catch block | 
| 119 |  |  |  |  |  |  | eBay::Exception::enableExceptions(); | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | try { | 
| 122 |  |  |  |  |  |  | myNewThrow(); | 
| 123 |  |  |  |  |  |  | } catch Error with { | 
| 124 |  |  |  |  |  |  | print "CATCHING myNewThrow().\n"; | 
| 125 |  |  |  |  |  |  | my $error = shift; | 
| 126 |  |  |  |  |  |  | if ($error->isa('myException') ) { | 
| 127 |  |  |  |  |  |  | print "myException ERROR: " . $error->error . "\n"; | 
| 128 |  |  |  |  |  |  | $error->foo(); | 
| 129 |  |  |  |  |  |  | } | 
| 130 |  |  |  |  |  |  | } finally { | 
| 131 |  |  |  |  |  |  | #optional cleanup code; | 
| 132 |  |  |  |  |  |  | print "I AM CLEANING UP.\n"; | 
| 133 |  |  |  |  |  |  | }; | 
| 134 |  |  |  |  |  |  |  | 
| 135 |  |  |  |  |  |  | sub myNewThrow { | 
| 136 |  |  |  |  |  |  | # log and (maybe) actually throw | 
| 137 |  |  |  |  |  |  | myException->ebay_throw( error => "This is a foo error." ); | 
| 138 |  |  |  |  |  |  | # or just throw and always throw regardless | 
| 139 |  |  |  |  |  |  | # myException->throw( error => "This is a foo error." ); | 
| 140 |  |  |  |  |  |  | } | 
| 141 |  |  |  |  |  |  |  | 
| 142 |  |  |  |  |  |  | 1; | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  |  | 
| 145 |  |  |  |  |  |  |  | 
| 146 |  |  |  |  |  |  | =cut | 
| 147 |  |  |  |  |  |  |  | 
| 148 |  |  |  |  |  |  | # Required Includes | 
| 149 |  |  |  |  |  |  | # --------------------------------------------------------------------------- | 
| 150 | 4 |  |  | 4 |  | 23 | use strict;                   # Used to control variable hell | 
|  | 4 |  |  |  |  | 8 |  | 
|  | 4 |  |  |  |  | 150 |  | 
| 151 | 4 |  |  | 4 |  | 19 | use warnings; | 
|  | 4 |  |  |  |  | 8 |  | 
|  | 4 |  |  |  |  | 116 |  | 
| 152 | 4 |  |  | 4 |  | 20 | use Data::Dumper; | 
|  | 4 |  |  |  |  | 7 |  | 
|  | 4 |  |  |  |  | 187 |  | 
| 153 | 4 |  |  | 4 |  | 21 | use Exporter; | 
|  | 4 |  |  |  |  | 7 |  | 
|  | 4 |  |  |  |  | 147 |  | 
| 154 | 4 |  |  | 4 |  | 2518 | use Error qw(:try); | 
|  | 4 |  |  |  |  | 11641 |  | 
|  | 4 |  |  |  |  | 29 |  | 
| 155 | 4 |  |  | 4 |  | 933 | use eBay::API::BaseApi; | 
|  | 4 |  |  |  |  | 9 |  | 
|  | 4 |  |  |  |  | 111 |  | 
| 156 | 4 |  |  | 4 |  | 6282 | use Devel::StackTrace; | 
|  | 4 |  |  |  |  | 17242 |  | 
|  | 4 |  |  |  |  | 367 |  | 
| 157 |  |  |  |  |  |  |  | 
| 158 |  |  |  |  |  |  | my $enabled = 0; | 
| 159 |  |  |  |  |  |  |  | 
| 160 |  |  |  |  |  |  | # Declare our exception types | 
| 161 | 4 |  |  |  |  | 73 | use Exception::Class ( 'eBay::Exception' => | 
| 162 |  |  |  |  |  |  | { isa => 'Exception::Class::Base', | 
| 163 |  |  |  |  |  |  | fields => ['package', 'file', 'line'], | 
| 164 |  |  |  |  |  |  | description => 'eBay API XML Parse exception.' }, | 
| 165 |  |  |  |  |  |  |  | 
| 166 |  |  |  |  |  |  | 'eBay::API::XmlParseException' => | 
| 167 |  |  |  |  |  |  | { isa => 'eBay::Exception', | 
| 168 |  |  |  |  |  |  | fields => ['schema'], | 
| 169 |  |  |  |  |  |  | description => 'eBay API XML Parse exception.' }, | 
| 170 |  |  |  |  |  |  |  | 
| 171 |  |  |  |  |  |  | 'eBay::API::UsageException' => | 
| 172 |  |  |  |  |  |  | { isa => 'eBay::Exception', | 
| 173 |  |  |  |  |  |  | fields => ['argnumber'], | 
| 174 |  |  |  |  |  |  | description => 'Incorrect subroutine call exception.' } | 
| 175 |  |  |  |  |  |  |  | 
| 176 | 4 |  |  | 4 |  | 4314 | ); | 
|  | 4 |  |  |  |  | 24647 |  | 
| 177 |  |  |  |  |  |  |  | 
| 178 | 4 |  |  | 4 |  | 4188 | use base qw(Error Exception::Class); | 
|  | 4 |  |  |  |  | 9 |  | 
|  | 4 |  |  |  |  | 662 |  | 
| 179 |  |  |  |  |  |  |  | 
| 180 |  |  |  |  |  |  | # dynamically extend CPAN Exception::Class to CPAN Error | 
| 181 |  |  |  |  |  |  |  | 
| 182 |  |  |  |  |  |  | BEGIN { | 
| 183 |  |  |  |  |  |  |  | 
| 184 | 4 | 50 |  | 4 |  | 1164 | push @Exception::Class::Base::ISA, 'Error' | 
| 185 |  |  |  |  |  |  | unless Exception::Class::Base->isa('Error'); | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | } | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | =pod | 
| 190 |  |  |  |  |  |  |  | 
| 191 |  |  |  |  |  |  | =head2 enableExceptions() | 
| 192 |  |  |  |  |  |  |  | 
| 193 |  |  |  |  |  |  | When called tells the exception framework to throw exceptions.  This has the | 
| 194 |  |  |  |  |  |  | effect of activating any exception handling logic in catch portion of a try/catch | 
| 195 |  |  |  |  |  |  | statement. | 
| 196 |  |  |  |  |  |  |  | 
| 197 |  |  |  |  |  |  | =cut | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  | sub enableExceptions { | 
| 200 | 0 |  |  | 0 | 1 |  | $enabled = 1; | 
| 201 |  |  |  |  |  |  | } | 
| 202 |  |  |  |  |  |  |  | 
| 203 |  |  |  |  |  |  | =pod | 
| 204 |  |  |  |  |  |  |  | 
| 205 |  |  |  |  |  |  | =head2 disableExceptions() | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | This reverses the effect of calling enableExceptions().  The default for the | 
| 208 |  |  |  |  |  |  | exception handling framework is for it to be disabled. | 
| 209 |  |  |  |  |  |  |  | 
| 210 |  |  |  |  |  |  | =cut | 
| 211 |  |  |  |  |  |  |  | 
| 212 |  |  |  |  |  |  | sub disableExceptions { | 
| 213 | 0 |  |  | 0 | 1 |  | $enabled = 0; | 
| 214 |  |  |  |  |  |  | } | 
| 215 |  |  |  |  |  |  |  | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  | =pod | 
| 218 |  |  |  |  |  |  |  | 
| 219 |  |  |  |  |  |  | =head2 ebay_throw() | 
| 220 |  |  |  |  |  |  |  | 
| 221 |  |  |  |  |  |  | Extract information from the exception being thrown, including a stack trace, | 
| 222 |  |  |  |  |  |  | and log this information with the API logging framework.  If exceptions are | 
| 223 |  |  |  |  |  |  | enabled, then call Exception::Class::throw() to throw the exception.  This will | 
| 224 |  |  |  |  |  |  | cause the exception handling logic in the catch portion of the try/catch statement | 
| 225 |  |  |  |  |  |  | to execute. | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  | =cut | 
| 228 |  |  |  |  |  |  |  | 
| 229 |  |  |  |  |  |  | sub ebay_throw { | 
| 230 | 0 |  |  | 0 | 1 |  | my @args = @_; | 
| 231 |  |  |  |  |  |  | #print Dumper(@args); | 
| 232 | 0 |  |  |  |  |  | my ($package, $filename, $line) = caller; | 
| 233 | 0 |  |  |  |  |  | my $trace = Devel::StackTrace->new; | 
| 234 | 0 |  |  |  |  |  | my $msg .= (shift) . " at ".$package . " " . $filename . " " . $line  . "\n" . $trace->as_string; | 
| 235 | 0 |  |  |  |  |  | while (@_) { | 
| 236 | 0 |  |  |  |  |  | $msg .= "\t" . (shift) . ": "; | 
| 237 | 0 |  |  |  |  |  | $msg .= (shift) . "\n" | 
| 238 |  |  |  |  |  |  | } | 
| 239 |  |  |  |  |  |  |  | 
| 240 |  |  |  |  |  |  | # log the error info | 
| 241 | 4 |  |  | 4 |  | 26 | no strict('subs'); | 
|  | 4 |  |  |  |  | 8 |  | 
|  | 4 |  |  |  |  | 256 |  | 
| 242 | 0 |  |  |  |  |  | eBay::API::BaseApi::_log_it($msg, eBay::API::BaseApi::LOG_ERROR); | 
| 243 | 4 |  |  | 4 |  | 21 | use strict('subs'); | 
|  | 4 |  |  |  |  | 18 |  | 
|  | 4 |  |  |  |  | 329 |  | 
| 244 |  |  |  |  |  |  |  | 
| 245 |  |  |  |  |  |  | # check to see if exceptions are enabled | 
| 246 | 0 | 0 |  |  |  |  | if ($enabled) { | 
| 247 | 0 |  |  |  |  |  | my $exception = shift @args; | 
| 248 | 0 |  |  |  |  |  | $exception->throw(@args); | 
| 249 |  |  |  |  |  |  | } | 
| 250 |  |  |  |  |  |  | } | 
| 251 |  |  |  |  |  |  |  | 
| 252 |  |  |  |  |  |  |  | 
| 253 |  |  |  |  |  |  | # Return TRUE to perl | 
| 254 |  |  |  |  |  |  | 1; |