Modify Warnings and Errors


We needed to add some application-specific contextual information to our errors and warnings in the logs, to help troubleshoot following a big (and not-thoroughly-tested) code rollout.

In the following sections you will find two methods similar to those we added to accomplish this. To keep things simple, let's assume we want to add a timestamp and the username to every error and warning.

Modifying warnings

To catch a warning, you simply want to set up a perl __WARN__ handler in your main application class. Near the dispatch method is a good place to do so.

package YourApp;
use Moose;
extends 'Catalyst';

# ... 

around dispatch => sub {
    my ($orig$self) = (shift,shift);

    local $SIG{__WARN__} = sub {
        my $warning = shift;

        # Prepend "[username @ timestamp] " to the warning
        my $prepend = '['
            . $self->user ? $self->user->username : 'unknown user'
            . ' - ' . time() . ']';

        # Do something with the warning. We're going to log it through Catalyst
        $self->log->warn($prepend . $warning);

    return $self->$orig(@_);

# ...

Modifying errors

Catalyst stores fatal errors in an arrayref available with $c->error(). We can simply modify the contents of this arrayref.

A good place to do this is before the finalize_error method provided by Catalyst::Engine.

Continuing the above example, we'll add the following to the YourApp class:

before finalize_error => sub {
    my $self = shift;
    if (scalar @$self->error }) {

        #  "[username @ timestamp] "
        my $prepend = '[' 
            . $self->user ? $self->user->username : 'unknown user'
            . ' - ' . time() . '';

        # prepend it to each error.
        for my $i ( 0 .. (scalar @{$self->error- 1) ) {
            $self->error->[$i] = $prepend . $self->error->[$i];


Thanks to mst, hobbs, and others from #catalyst

My tags:
Popular tags:
Powered by Catalyst
Powered by MojoMojo Hosted by Shadowcat - Managed by Nordaaker