1custom::failures(3)   User Contributed Perl Documentation  custom::failures(3)
2
3
4

NAME

6       custom::failures - Minimalist, customized exception hierarchy generator
7

VERSION

9       version 0.004
10

SYNOPSIS

12           package MyApp::failure;
13
14           use custom::failures qw/io::file io::network/;
15
16           # customize failure methods…
17

DESCRIPTION

19       This module works like failures but lets you define a customized
20       exception hierarchy if you need a custom namespace, additional
21       attributes, or customized object behaviors.
22
23       Because failure classes have an @ISA chain and Perl by default uses
24       depth-first-search to resolve method calls, you can override behavior
25       anywhere in the custom hierarchy and it will take precedence over
26       default "failure" behaviors.
27
28       There are two methods that might be useful to override:
29
30       •   message
31
32       •   throw
33
34       Both are described further, below.
35

USAGE

37   Defining a custom failure hierarchy
38           package MyApp::failure;
39
40           use custom::failures qw/foo::bar/;
41
42       This will define a failure class hierarchy under the calling package's
43       namespace.  The following diagram show the classes that will be created
44       (arrows denote 'is-a' relationships):
45
46           MyApp::failure::foo::bar --> failure::foo::bar
47                  |                        |
48                  V                        V
49           MyApp::failure::foo      --> failure::foo
50                  |                        |
51                  V                        V
52           MyApp::failure           --> failure
53
54       Alternatively, if you want a different namespace for the hierarchy, do
55       it this way:
56
57           use custom::failures 'MyApp::Error' => [ 'foo::bar' ];
58
59       That will create the following classes and relationships:
60
61           MyApp::Error::foo::bar --> failure::foo::bar
62                  |                        |
63                  V                        V
64           MyApp::Error::foo      --> failure::foo
65                  |                        |
66                  V                        V
67           MyApp::Error           --> failure
68
69       By having custom classes also inherit from a standard namespace, you
70       can throw a custom error class that will still be caught in the
71       standard namespace:
72
73           use Safe::Isa; # for $_isa
74           try {
75               MyApp::failure::foo::bar->throw;
76           }
77           catch {
78               if ( $_->$_isa( "failure::foo" ) ) {
79                   # handle it here
80               }
81           };
82
83   Adding custom attributes
84       Failure classes are implemented with Class::Tiny, so adding attributes
85       is trivially easy:
86
87           package MyApp::failure;
88
89           use custom::failures qw/foo::bar/;
90
91           use Class::Tiny qw/user/;
92
93       This adds a "user" attribute to "MyApp::failure" and all its subclasses
94       so it can be set in the argument to "throw":
95
96           MyApp::failure::foo->throw( { msg => "Ouch!", user => "me" } );
97
98       Be sure to load "Class::Tiny" after you load "custom::failures" so that
99       your @ISA is already set up.
100
101   Overriding the "message" method
102       Overriding "message" lets you modify how the error string is produced.
103       The "message" method takes a string (typically just the "msg" field)
104       and returns a string.  It should not produce or append stack trace
105       information.  That is done during object stringification.
106
107       Call "SUPER::message" if you want the standard error text prepended
108       ("Caught $class: ...").
109
110       For example, if you want to use String::Flogger to render messages:
111
112           package MyApp::failure;
113
114           use custom::failures qw/foo::bar/;
115           use String::Flogger qw/flog/;
116
117           sub message {
118               my ( $self, $msg ) = @_;
119               return $self->SUPER::message( flog($msg) );
120           }
121
122       Then you can pass strings or array references or code references as the
123       "msg" for "throw":
124
125           MyApp::failure->throw( "just a string"               );
126           MyApp::failure->throw( [ "show some data %s", $ref ] );
127           MyApp::failure->throw( sub { call_expensive_sub() }  );
128
129       Because the "message" method is only called during stringification
130       (unless you call it yourself), the failure class type can be checked
131       before any expensive rendering is done.
132
133   Overriding the "throw" method
134       Overriding "throw" lets you modify the arguments you can provide or
135       ensure that a trace is included.  It can take whatever arguments you
136       want and should call "SUPER::throw" with a hash reference to actually
137       throw the error.
138
139       For example, to capture the filename associated with file errors:
140
141           package MyApp::failure;
142
143           use custom::failures qw/file/;
144
145           use Class::Tiny qw/filename/;
146
147           sub throw {
148               my ( $class, $msg, $file ) = @_;
149               my $args = {
150                   msg => $msg,
151                   filename => $file,
152                   trace => failures->croak_trace,
153               };
154               $self->SUPER::throw( $args );
155           }
156
157           sub message {
158               # do something with 'msg' and 'filename'
159           }
160
161       Later you could use it like this:
162
163           MyApp::failure::file->throw( opening => $some_file );
164
165   Using BUILD
166       "Class::Tiny" supports "BUILD", so you can also use that to do things
167       with failure objects when thrown.  This example logs exceptions as they
168       are built:
169
170           use Log::Any qw/$log/;
171
172           sub BUILD {
173               my ($self) = @_;
174               $log->error( $self->message );
175           }
176
177       By using "message" instead of stringifying $self, we log the message
178       but not the trace (if any).
179

AUTHOR

181       David Golden <dagolden@cpan.org>
182
184       This software is Copyright (c) 2013 by David Golden.
185
186       This is free software, licensed under:
187
188         The Apache License, Version 2.0, January 2004
189
190
191
192perl v5.34.0                      2021-07-23               custom::failures(3)
Impressum