-1

I have a solution for this currently but it may not be the most versatile code. I know there is a way to use templates with placeholders for variables instead of putting the actual runtime parameters into the error message. Apologies if what I'm asking is unclear. I don't have a whole lot of knowledge on how to use templates.

 use constant {
    #list will contain more errors

    ERROR_SW => {
    errorCode => 727,
    message => sub{"Not able to ping switch $switch_ip in $timeout seconds"},
    fatal => 1,
    web_page => 'http://www.errorsolution.com/727',
    }
};

sub error_post {
    my ($error) = @_;
    print($error->{message}());   
}
    error_post(ERROR_SW);

I am trying to design it so that I can use placeholders for $switch_ip and $timeout instead of having to declare the message as a subroutine reference. Like below

 use constant {
    #list will contain more errors

    ERROR_SW => {
    errorCode => 727,
    message => "Not able to ping switch **{{switch_ip}}** in **{{timeout}}** seconds",
    fatal => 1,
    web_page => 'http://www.errorsolution.com/727',
    }
};

sub error_post {
    my ($error) = @_;
    print($error->{message});   
}
    error_post(ERROR_SW);

They also appear in code like so:

%%error%%

I'm not sure how to create the template which will handle the parameters. Again Apologies for being vague or not explaining this well.

Paul Russell
  • 179
  • 10
  • Not sure whether you real question is about good practises for Error handling or about templates. My answer assumes that you are really asking about error handling. – pmakholm Mar 11 '16 at 13:59

2 Answers2

2

I can't immediately see what this approach buys you that isn't provided by the printf format I explained before, but I suggest you use the Text::Template module to do it this way. It is less extensive than Template::Toolkit but perfectly adequate for your purposes

Here's what a program using Text::Template would look like. I hope it helps you

use strict;
use warnings 'all';

use Text::Template qw/ fill_in_string /;

use constant {
    ERROR_SW => {
        errorCode => 727,
        message   => 'Not able to ping switch {$switch_ip} in {$timeout} seconds',
        fatal    => 1,
        web_page => 'http://www.errorsolution.com/727',
    }
};

my $values = {
    switch_ip => '192.168.0.1',
    timeout   => 60,
};

sub error_post {
    my ($error) = @_;
    print( fill_in_string($error->{message}, hash => $values) );
}

error_post(ERROR_SW);

output

Not able to ping switch 192.168.0.1 in 60 seconds
Community
  • 1
  • 1
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • How could I make this work if the `$values` are actual parameters that the values aren't known? (they are known at runtime) – Paul Russell Apr 08 '16 at 16:36
  • @PaulRussell: Those values are already assigned at run time. You should have no problem using the code directly – Borodin Apr 09 '16 at 11:49
0

I would create a package for each error type in you project. Each error object should have the necessary attributes to describe the error and a as_string() method giving a human readable message.

These packages can be written using you normal Object oriented framework (e.g. Moose). With good old perl objects it could look like this:

package My::Error;

sub new {
    my ($class, %self) = @_;
    bless \%self, $class;
}

package My::Error::SW;
use parent 'My::Error';

sub as_string {
    my $self = shift;

    return sprintf "Not able to ping switch %s in %s seconds", $self->{switch_ip}, $self->{timeout};
}

There exists multiple frameworks for this on CPAN. One example is the Throwable modules which uses Moose.

Borodin
  • 126,100
  • 9
  • 70
  • 144
pmakholm
  • 1,488
  • 8
  • 23
  • The biggest problem with anything based on `Moose` is that, together with its dependencies, it is a *huge* bundle of code and can take many minutes to install – Borodin Mar 11 '16 at 14:08