NAME
Exception::Reporter - a generic exception-reporting object
VERSION
version 0.014
SYNOPSIS
Achtung! This is an experimental refactoring of some long-standing internal code. It might get even more refactored. Once I've sent a few hundred thousand exceptions through it, I'll remove this warning...
First, you create a reporter. Probably you stick it someplace globally accessible, like MyApp->reporter.
my $reporter = Exception::Reporter->new({
always_dump => { env => sub { \%ENV } },
senders => [
Exception::Reporter::Sender::Email->new({
from => 'root',
to => 'SysAdmins <sysadmins@example.com>',
}),
],
summarizers => [
Exception::Reporter::Summarizer::Email->new,
Exception::Reporter::Summarizer::File->new,
Exception::Reporter::Summarizer::ExceptionClass->new,
Exception::Reporter::Summarizer::Fallback->new,
],
});
Later, some exception has been thrown! Maybe it's an Exception::Class-based exception, or a string, or a Throwable object or who knows what.
try {
...
} catch {
MyApp->reporter->report_exception(
[
[ exception => $_ ],
[ request => $current_request ],
[ uploading => Exception::Reporter::Dumpable::File->new($filename) ],
],
);
};
The sysadmins will get a nice email report with all the dumped data, and reports will thread. Awesome, right?
OVERVIEW
Exception::Reporter takes a bunch of input (the dumpables) and tries to figure out how to summarize them and build them into a report to send to somebody. Probably a human being.
It does this with two kinds of plugins: summarizers and senders.
The summarizers' job is to convert each dumpable into a simple hashref describing it. The senders' job is to take those hashrefs and send them to somebody who cares.
METHODS
new
my $reporter = Exception::Reporter->new(\%arg);
This returns a new reporter. Valid arguments are:
summarizers - an arrayref of summarizer objects; required
senders - an arrayref of sender objects; required
dumper - a Exception::Reporter::Dumper used for dumping data
always_dump - a hashref of coderefs used to generate extra dumpables
caller_level - if given, the reporter will look n frames up; see below
The always_dump
hashref bears a bit more explanation. When "report_exception"
is called, each entry in always_dump
will be evaluated and appended to the list of given dumpables. This lets you make your reporter always include some more useful information.
...but remember! The reporter is probably doing its job in a catch
block, which means that anything that might have been changed local
-ly in your try
block will not be the same when evaluated as part of the always_dump
code. This might not matter often, but keep it in mind when setting up your reporter.
In real code, you're likely to create one Exception::Reporter object and make it globally accessible through some method. That method adds a call frame, and Exception::Reporter sometimes looks at caller
to get a default. If you want to skip those intermedite call frames, pass caller_level
. It will be used as the number of frames up the stack to look. It defaults to zero.
report_exception
$reporter->report_exception(\@dumpables, \%arg);
This method makes the reporter do its job: summarize dumpables and send a report.
Useful options in %arg
are:
reporter - the program or authority doing the reporting; defaults to
the calling package
handled - this indicates that this exception has been handled and that
the user has not seen a terrible crash; senders might use
this to decide who needs to get woken up
extra_rcpts - this can be an arrayref of email addresses to be used as
extra envelope recipients by the Email sender
Each entry in @dumpables
is expected to look like this:
[ $short_name, $value, \%arg ]
The short name is used for a few things, including identifying the dumps inside the report produced. It's okay to have duplicated short names.
The value can, in theory, be anything. It can be undef
, any kind of object, or whatever you want to stick in a scalar. It's possible that extremely exotic values could confuse the "fallback" summarizer of last resort, but for the most part, anything goes.
The %arg
entry isn't used for anything by the core libraries that ship with Exception::Reporter, but you might want to use it for your own purposes. Feel free.
The reporter will try to summarize each dumpable by asking each summarizer, in order, whether it can_summarize
the dumpable. If it can, it will be asked to summarize
the dumpable. The summaries are collected into a structure that looks like this:
[
[ dumpable_short_name => \@summaries ],
...
]
If a given dumpable can't be dumped by any summarizer, a not-very-useful placeholder is put in its place.
The arrayref constructed is passed to the send_report
method of each sender, in turn.
collect_summaries
$reporter->report_exception(\@dumpables);
This method is used by "report_exception" to convert dumpables into summaries. It may be called directly by summarizers through $self->reporter->collect_summaries(\@dumpables);
if your summarizers receive dumpables that may be handled by another summarizer. Be wary though, because you could possibly create an endless loop...
AUTHOR
Ricardo Signes <rjbs@cpan.org>
CONTRIBUTORS
Matthew Horsfall <wolfsage@gmail.com>
Tomohiro Hosaka <bokutin@bokut.in>
COPYRIGHT AND LICENSE
This software is copyright (c) 2010 by Ricardo Signes.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.