The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

Fault

Synopsis

Fault.pm generates and exports fault (error) symbols. These symbols are a combination of fault classification and a globally unique fault ID.

Description

Fault symbols are scalar whole numbers with encode/decode functions to combine and split the classification and the assigned code.

These error symbols are called faults to distinguish capturing a unexpected outcome ( such as a system error-code or null value ), from the computational failure; the more common use of the term error.

Combining an internal code with a general classification of the component's ability to further function cleanly promotes an implementation issue (white-box) to an abstract fault when it propagates outside of the name-space that defines it (black-box).

The distinction between fault and error allows lightweight handling of simple responses: choosing protocol responses through an API for example.

Complex cases such as selecting fall-back or repair responses can be cleanly implemented with separation between detection, diagnostics, and error handling. Handling unavailable services or corrupted state are examples of the more complex scenarios.

Classification of faults

Classification of faults is by how the unexpected behavior has altered the state between operations, or it's ability to continue.

when a error code propagates outside of the black-box in which it is defined the specificity of the error code is no longer meaningful outside of that black-box.

The catching/receiving context can use the classification minimally or the code specifically depending on how tight the coupling between the components is.

Definition

The classification values are defined with names within fault so that classification can be determined by comparison.

$Fault::FATAL

unrecoverable error, value 0 for an easy test.

$Fault::REJECT

recoverable; no state changed (example: input validation failed)

$Fault::CHKPT

recoverable; state is checkpoint-ed

$Fault::FAULT

recoverable; unknown state

Defining fault symbols

The Fault.pm interface for creating fault symbols is import, ie the 'use' directive.

To define (import) fault symbols list the fault names, followed by a single classification or an array of multiple classifications separated with: ',' or '=>'

    use Fault ( burning => [ fatal, fault ] , stabbing => fatal ); # import fault symbols

fault will create scalars in your package symbol table that can be used like this:

    $BURNING_FATAL , $BURNING_FAULT , $BURNING_ERROR
    $STABBING_FATAL , $STABBING_ERROR

The code is always on the left, with the classification on the right; matching the declaration pattern for intuitive mapping from import to referencing of the symbols.

the _ERROR export is the globally unique error id by itself. This is created automatically per-fault.

w/o importing

When using the module (definitions) without importing any fault symbols use empty parentheses.

    use Fault();                                                   # use the module without generating symbols

Using fault symbols internally (white-box)

Fault symbols can be used within the module they are defined by treating them as named simple ( whole ) numbers. Simple comparison operations are all that is needed.

   eval {
      die $BURNING_FAULT if ( some_error() );   // detect here
   };

   if ( $@ == $BURNING_FAULT ) {
      // recover here
   }
Fault::code()

the Fault::code() function returns the code of the component. This is useful when the specific error without the classification is needed.

  if( Fault::code( $BURNING_FATAL  ) != $BURNING_ERROR ) {
    print "imploded !";
    exit 1;
  }

Using fault symbols externally (black-box)

Fault symbols that propagate outside the defining name-space are usable with the classification component only.

Fault::status()

the Fault::status() function returns the classification component of a fault symbol. This can be compared against the named values Fault::FATAL,...

    if ( Fault::status( $@ ) == $Fault::REJECT ) {
       goto do_over;
    }

    if ( Fault::status( $@ ) == $Fault::FATAL ) {
       print "died horribly\n";
       exit 1;
    }

blessed fault symbols

it is very useful to bless fault symbols to disambiguate them from standard exceptions.

    die new Fault ( $BURNING_FATAL );

    if ( ref $@ eq 'Fault' ) {
        exit 1 if ( $@->status() == $Fault::FATAL );
    }

See Also

Author

Mike Mattie email = codermattie@gmail.com

copyright

Copyright Mike Mattie 2007. All Rights reserved.

License

LGPL.

TODO

intergrate with Fault unaware code

Essentially the fault symbols need to stringify in a string context. This should cover most of the error traps.

improve examples

The Fault::code() example is a punt, come up with a better scenario

add strategies

Document strategies for using Fault effectively.