manakai

Message::Util::Error

manakai's Common Error Handling Module

SYNOPSIS

If you want to catch an exception, whose class is YourExceptionClass, throwed by a class YourClass:

  use YourClass;
  use Message::Util::Error;
  
  my $obj = YourClass->new;
  
  try {
    $obj->method_that_throw_an_eception;
  } catch YourExceptionClass with {
    my $err = shift;
    if ($err->type eq 'NOT_SUPPORTED_ERR') {
      $err->throw; # die unless catched by upper-level |try| clause (if any)
    } else {
      warn $err;
    }
  };

If you want to build a class YourClass that throws an exception based on Message::Util::Error:

  package YourClass;
  
  sub method_that_throw_an_exception ($) {
    my $self = shift;
    report YourExceptionClass
        -object => $self,
        -type => 'EXAMPLE_ERR',
        -subtype => 'EXAMPLE_SPECIFIC_ERR';
  } # method_that_throw_an_exception
  
  ## |report| calls back this method.  If this method |throw|s
  ## the exception, then it is really thrown.
  sub ___report_error ($$) {
    my ($self, $err) = @_;
    if ($err->type_def->{level} eq 'warning') {
      warn $err;
    } else {
      $err->throw;
    }
  } # ___report_error
  
  package YourExceptionClass;
  use Message::Util::Error;
  push our @ISA, 'Message::Util::Error';
  
  sub ___error_def () {
    return {
      EXAMPLE_ERR => {
        -description => q<An example error condition>,
        -subtype => {
          EXAMPLE_SPECIFIC_ERR => {
            -description => q<A specific example error condition>,
          },
        },
        level => 'fatal',
      },
    };
  } # ___error_def

DESCRIPTION

Various manakai classes throws exceptions, in particular DOMExceptions in DOM implementation classes. In addition, it might report other kinds of errors, such as DOMError as defined in DOM Level 3 Core specification. This module, Message::Util::Error, provides an integrated framework for reporting exceptions, errors, warnings, and so on.

The Message::Util::Error exception framework is built on the top of the Perl module Error, which apply to Perl scripts the try and catch functionalities. Exceptions thrown using Message::Util::Error exception framework are also able to be catched by the catch clause as in the original Error module. For more information on usage for try, catch, and other clauses, see the documentatin for the Error module. This document describes some Message::Util::Error-specific conventions, mainly targeted for manakai module authors.

For other usages of the framework, such as DOMError, see documentation for each module.

This module is part of manakai.

ACCESSING ERROR INFORMATION

Loading try and catch Support

If you'd like to use try and catch clauses, you have to import these names by:

  use Message::Util::Error;

Note that the example above is equivalent to:

  use Error qw(:try);

except that in the former example Message::Util::Error module is also loaded if not yet.

Methods on Error Objects

Any method defined on an Error object is also available for Message::Util::Error objects with the same semantics (though some might be overridden). In addition, a few methods are added for Message::Util::Error objects.

$code = $err->code;

Returns the code of the error.

If the definition for the error type has a code associated, then it is returned. Otherwise, 0 is returned.

This method is added for DOM compatibility.

$subtype = $err->subtype;

Returns the subtype of the error, if specified when the error object is created, or undef otherwise.

$text = $err->text;

Returns the text of the error.

This method is defined in Error module but overridden. If the definition for the error subtype, if any, has a description, then it is returned. Otherwise, if the definition for the error type has a description, then it is returned. Otherwise, same as Error's definition, i.e. the text specified when the Error object is created, if any, or undef otherwise, is returned.

$text = $err->type;

Returns the type of the error specified when the error is created.

$def = $err->type_def;

Returns the definition for the error type, if any, or the definition for the UNKNOWN type, otherwise. For the content of the error type definition, see "Error Type Definitions". Applications MUST NOT modify the error type definition. If modified then the result is undefined and it might make the error handling behaviour inconsistent or incorrect.

$value = $err->value; $value = 0+$err;

Returns the value that can be associated with the error.

This method is defined in Error module but overridden. If the definition for the error type has a code associated, then it is returned. Otherwise, same as Error's definition, i.e. the value specified when the Error object is created, if any, or undef otherwise, is returned.

THROWING ERRORS

@@

1. Define an error class.

2. Define the ___report_error method to the class whose methods will report errors. (REQUIRED if you use report.)

3. Define an error message template class. (REQUIRED if you want to extend the error message parameter set.)

4. Put report or throw where you want to report or throw an error.

5. Ensure the error class is loaded when any statement added by Step 4 is executed.

Error Classes

@@

Error Type Definitions

@@

Error type:

-code

Numeric error code for the type. If specified, it MUST be a number.

-description

A template that is used to create the description for an error with that type. @@ See @@ for template syntax.

-subtype

A reference to hash that contains pairs of error subtype nams and error subtype definitions. It MAY contain zero or more error subtypes.

Error subtype:

-description

A template that is used to create the description for an error with that subtype. @@ See @@ for template syntax.

Any other value starts with - is reserved for future extension and MUST NOT be used for any purpose until it is eventually defined. Values not start with - MAY be used for subclass-specific error type/subtype properties.

Throwing an Error

@@

-def (MUST NOT be specified)

The definition for the error type.

This parameter MUST NOT be specified when a Message::Util::Error object is created. It will be supplied by the constructor of the error object. If any value is specified, it will be ignored.

If no definition for the error type is found, then the definition for the UNKNOWN type is used; if there is no such definition, then the error constructor dies.

-file (MUST NOT be specified)

The file name where an error is reported.

This parameter MUST NOT be specified when a Message::Util::Error object is created. It will be supplied by the constructor of the error object. If any value is specified, it will be ignored.

-line (MUST NOT be specified)

The line number where an error is reported.

This parameter MUST NOT be specified when a Message::Util::Error object is created. It will be supplied by the constructor of the error object. If any value is specified, it will be ignored.

-object

The object for which an error is reported.

If specified, the value MUST be an object that has a ___report_error method. Otherwise, Perl will report some error.

-package (MUST NOT be specified)

The package name where an error is reported.

This parameter MUST NOT be specified when a Message::Util::Error object is created. It will be supplied by the constructor of the error object. If any value is specified, it will be ignored.

-stacktrace (MUST NOT be specified)

The trace of the function call stack (used by Error module).

This parameter MUST NOT be specified when a Message::Util::Error object is created. It will be supplied by the constructor of the error object. If any value is specified, it will be ignored.

-stacktrace_ (MUST NOT be specified)

The trace of the function call stack (used by Message::Util::Error module).

This parameter MUST NOT be specified when a Message::Util::Error object is created. It will be supplied by the constructor of the error object. If any value is specified, it will be ignored.

-subtype

The subtype of the error. It may or may not be specified.

-text

The text of the error. Note that this option is less useful in Message::Util::Error where -description in error type/subtype definitions take precedence in the text method.

-type (REQUIRED)

The error type.

This parameter MUST be specified when a Message::Util::Error object is created. If this option is missing when creating an error object, then the error constructor dies.

-value

The value of the error. Note that this option is less useful in Message::Util::Error where -code in error type definition take precedence in the value method.

Any other value starts with - is reserved for future extension and MUST NOT be used for any purpose until it is eventually defined. Values not start with - MAY be used for subclass-specific error properties.

___report_error Method

@@

Error Message Construction

@@ NEED TO BE REWRITTEN

Human readable error message text, returned by text method, is generated from description parameter of error definition.

Format defined by Message::Util::Formatter is used to specify description parameter and it is processed by the formatter.

sub ERROR_SUBCLASS::_FORMATTER_PACKAGE_ { return $class_name }

Subclass can define _FORMATTER_PACKAGE_ method to define class name of the formatter. Defaulted to Message::Util::Error::formatter.

Unless you wish to use additional rules in template text (description parameter), you don't need to define this method in your subclass.

Class returned by this method MUST be a subclass (descender class) of Message::Util::Formatter::Base.

Formatter Message::Util::Error::formatter

In addition to rules defined in Message::Util::Formatter::Text, formatter Message::Util::Error::formatter defines some rules:

%name;

Error type name (-type parameter specified when error is thrown)

%t (name => parameter-name);

Parameter value specified when error is thrown

EXAMPLE

@@ MAYBE WE CAN REMOVE THIS SECTION

To make a new error class:

  package SomeExceptionClass;
  use Message::Util::Error;
  push our @ISA, 'Message::Util::Error';
  
  ## [REQUIRED] Error types
  sub ___error_def {
    ## Returns a reference to hash defining error type
    return {
      ERROR_NAME => {
        description => q(%name;: %t (name => what); is bad),
        level => 'fatal',
        ...
      },
      WARNING_NAME => {
        description => q(%name;: %t (name => what); might be bad),
        level => 'warn',
        ...
      },
      ...
    };
  }
  
  ## [OPTIONAL] Package name of formatter constructing error message
  ##            (Default: Message::Util::Error::formatter)
  sub _FORMATTER_PACKAGE_ () { 'SomeFormatterClass' }

Throwing exception:

  use SomeExceptionClass;
  ...
  do something;
  ...
  throw SomeExceptionClass -type => 'ERROR_NAME',
                           what => 'Example';

If you implements an object-oriented class:

  package SomeModule;
  use SomeExceptionClass;
  
  sub some_method {
    my $self = shift;
    ...
    report SomeExceptionClass
      -type => 'ERROR_NAME',
      what => 'Non-oo programing',
      -object => $self, method => 'some_method'
        unless $oo;
    ...
    report SomeExceptionClass
      -type => 'WARNING_NAME',
      what => 'This module',
      -object => $self, method => 'some_method';
    ...
  }
  
  ## If you use "report", you must implements this internal method
  sub ___report_error ($$;%) {
    my ($self, $err, %option) = @_;
    ## Throwing if fatal
    if ($err->{def}->{level} eq 'fatal') {
      $err->throw;
      print "This text never printed";
    ## Otherwise warning only
    } else {
      warn $err->stringify;
      print "This text IS printed";
    }
  }

SEE ALSO

Error

Message::DOM::DOMException

Message::DOM::DOMError

AUTHOR

Wakaba <wakaba@suikawiki.org>

LICENSE

Copyright 2003-2007 Wakaba <wakaba@suikawiki.org>

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.