failures(3pm)
π failures(3pm) β the lil' manpage, but make it cute π
okay so bestie, welcome to failures, a page from the User Contributed Perl Documentation section of your man pages (3pm, iykyk). Buckle up, we're gonna make exception hierarchies not boring π
β¨ NAME β¨
failures β a minimalist exception hierarchy generator. yes, minimalist. it does one thing and it does it gorgeously π
πΈ VERSION πΈ
version 0.004
π¦ SYNOPSIS π¦
use failures qw/io::file io::network/;
use Try::Tiny;
use Safe::Isa; # for $_isa
try {
process_file or
failure::io::file->throw("oops, something bad happened: $!");
}
catch {
if ( $_->$_isa("failure::io::file") ) {
...
}
elsif( $_->$_isa("failure::io") ) {
...
}
elsif( $_->$_isa("failure") ) {
...
}
else {
...
}
}
like. look at that. hierarchies that slap π
π DESCRIPTION π
This module lets you define an exception hierarchy quickly and simply. no drama, no 400 lines of boilerplate, just vibes β¨
Here were my design goals:
- minimalist interface
- 80% of features in 20% of lines of code
- depend only on core modules (nearly achieved)
- support hierarchical error types
- identify errors types by name (class) not by parsing strings
- leave (possibly expensive) trace decisions to the thrower
Currently, failures is implemented in under 70 lines of code. under 70 lines. she's tiny and she ate π₯
Failure objects are implemented with Class::Tiny to allow easy subclassing (see custom::failures), but Class::Tiny only requires core modules, so other than that exception, the 'core only' goal is achieved. (one tiny little exception to the core-only goal, bestie, we're being honest here π)
π USAGE π
π Defining failure categories
use failures qw/foo::bar foo::baz/;
This will define the following classes in the failure namespace:
failurefailure::foofailure::foo::barfailure::foo::baz
Subclasses inherit, so failure::foo::bar is-a failure::foo and failure::foo is-a failure. it's giving family tree, it's giving lineage, it's giving inheritance π
π Attributes
A failure class has three attributes: msg, payload, and trace. Their usage is described below. Accessors exist for all three. three attributes, three accessors, no notes π
π§ Throwing failures
The throw method of a failure class takes a single, optional argument that modifies how failure objects are stringified.
If no argument is given, a default message is generated if the object is stringified:
say failure::foo::bar->throw;
# Caught failure::foo::bar
With a single, non-hash-reference argument, the argument is used for the msg attribute and is appended if the object is stringified.
say failure::foo::bar->throw("Ouch!");
# Caught failure::foo::bar: Ouch!
With a hash reference argument, the msg key provides the string to append to the default error. If you have extra data to attach to the exception, use the payload key:
failure::foo::bar->throw({
msg => "Ouch!",
payload => $extra_data,
});
If an optional trace key is provided, it is appended if the object is stringified. To loosely emulate die and provide a simple filename and line number, use the failure->line_trace class method:
failure::foo::bar->throw({
msg => "Ouch!",
trace => failure->line_trace,
});
# Caught failure::foo::bar: Ouch!
#
# Failure caught at <FILENAME> line <NUMBER>
To provide a trace just like the Carp module (including respecting @CARP_NOT) use the croak_trace or confess_trace class methods:
failure::foo::bar->throw({
msg => "Ouch!",
trace => failure->croak_trace,
});
# Caught failure::foo::bar: Ouch!
#
# Failure caught at <CALLING-FILENAME> line <NUMBER>
failure::foo::bar->throw({
msg => "Ouch!",
trace => failure->confess_trace,
});
# Caught failure::foo::bar: Ouch!
#
# Failure caught at <FILENAME> line <NUMBER>
# [confess stack trace continues]
You can provide a trace key with any object that overrides stringification, like Devel::StackTrace:
failure::foo::bar->throw({
msg => "Ouch!",
trace => Devel::StackTrace->new,
});
# Caught failure::foo::bar: Ouch!
#
# [stringified Devel::StackTrace object]
π«Ά Catching failures
Use Try::Tiny, of course. Within a catch block, you know that $_ is defined, but it still might be an unblessed reference or something that is risky to call isa on. If you load Safe::Isa, you get a code reference in $_isa that calls isa only on objects.
So catching looks like this:
use Try::Tiny;
use Safe::Isa;
try { ... }
catch {
if ( $_->$_isa("failure::foo") ) {
# handle it
}
};
If you need to rethrow the exception, just use die:
elsif ( $_->$_isa("failure") ) {
die $_;
}
π Overriding failure class behavior
See custom::failures. (go read it, it's right there π)
β SEE ALSO β
There are many error/exception systems on CPAN. This one is designed to be minimalist. (she's not like the other exception modules π )
If you have more complex or substantial needs, people I know and trust seem to be recommending:
- Throwable β exceptions as a Moo/Moose role
- Throwable::X β Throwable extended with extra goodies
Here are other modules I found that weren't appropriate for my needs or didn't suit my taste:
- Class::Throwable β no hierarchy and always builds a full stack trace
- Error::Tiny β blends Try::Tiny and a trivial exception base class
- Exception::Base β complexity on par with Exception::Class, but highly optimized for speed
- Exception::Class β once highly recommended, but even the author now suggests Throwable
- Exception::Simple β very simple, but always uses
callerand has no hierarchy - Exception::Tiny β not bad, but always uses
callerand setting up a hierarchy requires extra work - Ouch β simple, well-thought out, but no hierarchy; also cutesy function names
Here are some that I'm very dubious about:
- Err β alpha since 2012
- Error β no longer recommended by maintainer
- errors β "still under design" since 2009
- Exception β dates back to 1996 and undocumented
not the "alpha since 2012" π the way some of these have been in limbo longer than some of us have been alive. respect though, we don't do mean here π«Ά
π SUPPORT π
π Bugs / Feature Requests
Please report any bugs or feature requests through the issue tracker at <https://github.com/dagolden/failures/issues>. You will be notified automatically of any progress on your issue. (bestie you'll literally get pinged, no ghosting here β¨)
π Source Code
This is open source software. The code repository is available for public review and contribution under the terms of the license.
<https://github.com/dagolden/failures>
git clone https://github.com/dagolden/failures.git
π AUTHOR π
David Golden <dagolden@cpan.org>
πΈ CONTRIBUTOR πΈ
Michael Jemmeson <mjemmeson@cpan.org>
π¦ COPYRIGHT AND LICENSE π¦
This software is Copyright (c) 2013 by David Golden.
This is free software, licensed under:
The Apache License, Version 2.0, January 2004
okay that's the whole page bestie, you're officially a failures expert now π
this lil' cutie lives on perl v5.36.0, and this version of the page is dated 2022-12-07. go forth and throw your exceptions with main character energy π β¨
π¦ where this page comes from
- debian bookworm: libfailures-perl 0.004-3 Β· Apache-2.0
- debian trixie: libfailures-perl 0.004-3 Β· Apache-2.0
- ubuntu noble: libfailures-perl 0.004-3 Β· Apache-2.0
- ubuntu resolute: libfailures-perl 0.004-3 Β· Apache-2.0
- ubuntu stonking: libfailures-perl 0.004-3 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms