      Errors::Errors - Module for error/die/exit/abort proceeding.
      
       Errors module allows you to handle and proceed a large list of errors/signals

      Complete list of methods are shown below:

            attach :: content :: detach :: die :: error :: exit :: install :: 
            header :: print :: uninstall


      SYNOPSIS

            use Errors::Errors;

            use strict;

            my $obj = Errors::Errors->new();

            $obj->content(0);
            $obj->header();
            $obj->attach('xreader'); # Attach sub object (sobject) for error of 
            type 'xreader'.
            $obj->attach('myown'); # Attach sub object for error of type 'myown'.

            my $hash = {
                name=>'July',
                born_year=>'81',
            };

            $obj->attach_object('xreader',$hash); # Hash ref or object

            $obj->install('onTerm',\&custom); # Install sub for term event.
            $obj->install('onError',\&anysub,'xreader'); 
            # Install sub for xreader sobject which will be called when error 
            occure.
            $obj->install('onExit',\&leave); # Install sub for exit event.
            $obj->install('onTerm',\&custom,'myown'); # Install additional term 
            sub for 'myown' sobject.

            $obj->error(7,'xreader'); # Set error '7' for 'xreader' sobject and 
            force execution of error chain.

            #my $h = $obj->fetch_object('xreader');  # Fetch attached object 
            from xreader.
            #$obj->print($h->{name}."\n");

            $obj->uninstall('onError','xreader'); # Remove 'xreader' sub from 
            'error' chain.

            $obj->detach_object('xreader'); # Remove attached object from 
            xreader.
            $obj->detach('xreader'); # Remove xreader (and attached objects).

            $obj->install('onTimeOut',\&timeout); # Install timeout sub routine.
            eval 'alarm(1);'; # Force alarm after 1s
            sleep(2); # Wait 2 sec, so alarm will be activeted and 'timeout' 
            chain will be turned.
            #Note: Press CTRL+C to active 'INT' signal ('onTerm' event) before 
            time to flow out.

            #$obj->exit(); # Force exit of program.
            #$obj->die(); # Force die of program.

            #By default script close 'normally', so 'destroy' chain will be 
            executed.
            sub custom {
              my $obj = shift; # 'Errors' object
              my %in = @_;
              my $type = $in{'type'}; # Error type: 'term'
              my $name = $in{'name'}; # Custom error name
              my $sig = $in{'signal'}; # Invoked signal (term,quit,pipe...)
              # ...blah...blah...
              print "Custom($name)\n";
            }
            sub leave {
              my $obj = shift;
              my %in = @_;
              my $type = $in{'type'}; # Error type: 'exit','die','destroy'
              my $err = $in{'error'}; # Error value
              my $name = $in{'name'}; # Custom error name
              my $params = $in{'params'}; # Additional parameters (ref to @)
              my @params = @$params;
              # ...blah...blah...
              print "$type\n";
            }
            sub timeout
            {
              my $obj = shift;
              my %in = @_;
              my $type = $in{'type'}; # Error type: 'term'
              my $name = $in{'name'}; # Custom error name
              my $sig = $in{'signal'}; # Invoked signal: 'alrm'
              # ...blah...blah...
              print "Timeout\n";
            }
            sub anysub {
              my $obj = shift;
              my %in = @_;
              my $type = $in{'type'}; # Error type: 'error'
              my $err = $in{'error'}; # Error message
              my $name = $in{'name'}; # Custom error name
              my $to = $in{'to'}; # Message is sent "to" 
              my $params = $in{'params'}; # Additional parameters (ref to @)
              my @params = @$params;

              if($name eq $to && $to eq 'xreader')
              {
                $obj->print ("Error in Xreader!!!\n"); # If error is raised in 
            'xreader'
                my $h = $obj->fetch_object('xreader');
                $obj->print ($h->{born_year}."\n");
              }
             else
              {
               $obj->print ("Error in ... I don't know ;-)!!!\n");
              }
            }



      Install

            As any other 'CPAN' module you just have to do follow simple steps 
            to complete installation:

            tar -zxvf Errors-1.02.tar.gz
            cd Errors-1.02
            perl Makefile.PL
            make
            make test
            make install
            make clean

            Note: In WebTools engine this module is already installed!


      Getting Started

              First question is: Why I have to use Errors module in my Perl 
            program?
            In large projects you have to use many libraries, modules and of 
            course you have to catch all errors in, also in some cases you need 
            to make some finalize procedures at the end of your scripts. To do 
            that you may need to write subs for different errors, to write code 
            for interrupts/events/signals but what structure you use? None? Huh! 
            You just write code and grubby you program! It's a disgrace. 
             This module offer to you and your scripts centralize errors 
            handling and proceeding system.

            Comprehensive example:
              Let guess, that we have to develop script (no matter whether it is 
            Web based or a console application), which, as any professional 
            script, needs to care about occurred errors.
            In general case you have to implement a sub for showing an error 
            messages; logging code and in extreme situations to send mails to 
            your support team; code which will protect you from fatal errors; 
            code which will protect your script from infinitive loops.
              Described example is really superficial, but good enough to have 
            an idea about enormous requirement of error handling system like 
            this.
              Solution for lyric problem above is shown bellow:

            use Errors::Errors;

            use strict; 
            my $obj = Errors::Errors->new();
            $obj->attach('display');  # Virtual 'display' object (sobject)
            $obj->attach('logs');      # Virtual 'logs' object (sobject)
            $obj->install('onExit',\&catch_exit); # Catch exit.
            $obj->install('onError',\&event_handler,'display'); # Print error to 
            display
            $obj->install('onError',\&event_handler,'logs'); # Do same to your 
            hdd
            $obj->install('onTimeOut',\&timeout); # Handle overstep time limit.
            eval 'alarm(100);'; # Give 100 seconds lifetime to your script.
            eval q|
            #... code which may fail with fatal error!
            $obj->error('Error!','display'); # Force error
            $obj->error('Error!','logs'); # Force error
            $obj->exit();
            # exit() and $obj->exit() will close you application NOT only the 
            eval() block!
            # however exit() will trigger 'destroy' event, but $obj->exit() will 
            trigger 'exit' event!
            |;

            # Due 'eval' code above, following lines will not be executed!
            while(1)
            {
              # Any action which may bring application to infinitive loop.
              # After 100 sec this problem will be busted
            }
            sub event_handler
            {
              my $obj = shift;
              my %in = @_;
              my $type = $in{'type'}; # Error type: 'error'
              my $err = $in{'error'}; # Error message
              my $name = $in{'name'}; # Custom error name
              my $to = $in{'to'}; # Message is sent "to"
              my $params = $in{'params'}; # Additional parameters (ref to @)
              my @params = @$params;

              if($name eq $to && $to eq 'display')
              {
                # Print your error message...
                print "Error: $err (invoked for $name)\n";
              }
              if($name eq $to && $to eq 'logs')
               {
                 # Log your error message to hdd...
                 print "Error: $err (invoked for $name)\n";
               }
            }
            sub timeout
            {
              my $obj = shift;
              my %in = @_;
              my $type = $in{'type'}; # Error type: 'term'
              my $name = $in{'name'}; # Custom error name
              my $sig = $in{'signal'}; # Invoked signal: 'alrm'

              $obj->error('Timeout!', 'display');
              $obj->error('Timeout!', 'logs');
            }
            sub catch_exit
            {
              my $obj = shift;
              my %in = @_;
              my $type = $in{'type'}; # Error type: 'exit','die','destroy'
              my $err = $in{'error'}; # Error value
              my $name = $in{'name'}; # Custom error name
              my $params = $in{'params'}; # Additional parameters (ref to @)
              my @params = @$params;
              if($type eq 'exit')
               {
                 # Oops your code use 'exit' to abort script...
                 $obj->error('Oops!','display');
                 # ...
               }
            }


      How It Works?

              First you must to create one object for your program:
            use Errors::Errors;
            $obj = Errors::Errors->new();
            This object will contain pointers to your subs that handle occurred 
            errors.
            This module can handle follow base errors/events:
            exit(onExit), die(onExit), TERM/STOP/PIPE/QUIT/HUP/INT(onTerm), 
            ALRM(onTimeout), and custom errors(onError).
            If you want to do something when your script ends, set your custom 
            sub:
            $obj->install('onExit',\&leave);
            where \&leave is pointer to your sub 'leave'. When your script ends 
            your sub program 'leave' will be executed before the end. That will 
            be happened at the end of $obj scope i.e. in DESTROY section of 
            module. Also you can provoke execution of 'leave' if you write 
            follow line in program:

            $obj->exit($code_error);
            or
            $obj->die($code_error);
            If you want to handle ALRM signal write line like this:
            $obj->install('onTimeout',\&custom);
            where 'custom' is your custom sub that handle ALRM signal.
            To handle TERM/STOP/PIPE/QUIT/HUP/INT signals use follow like:
            $obj->install('onTerm',\&custom);
            where 'custom' is your custom sub that handle listed signals.
            If you want to initialize your custom errors write code bellow:
            $obj->install('onError',\&anysub);
            So when you call method bellow, somewhere in script, you will rise 
            execution of 'anysub'!
            $obj->error($code_error);
            Of course all your subs will receive additional parameters so you 
            will be able to find reason for errors (and respective error codes). 
            See SYSNOPSIS above.
            In single script these methods are strong enough, but if you have a 
            complex program with lot of libraries/modules you may want to have a 
            single 'errors' object for all your libraries/modules. But how you 
            can handle TERM signal for all yours different libraries??? The idea 
            is quite simple, we will still continue to use our global (single) 
            object, but we will create "sub objects" for all additional 
            libraries/modules! 
            To add new sub object do follow:
            $obj->attach('some');
            This will create sub object called 'some'. To install 'onTerm' 
            signal for this sub object (SObject) do follow:
            $obj->install('onTerm',\&custom,'some');
            Also to catch 'exit' for SObject call:
            $obj->install('onExit,',\&leave,'some');
            To rise custom error for 'some' SObject, call:
            $obj->error($code_error,'some',@additional_parameters);
            To exit&#8230;:
            $obj->exit($code_error,'some',@additional_parameters);
            &#8230; and so on.
            Note:
            $obj->error($code_error,'some');
            will rise error in 'some' sub object
            $obj->error($code_error);
            will rise error in 'main' object!!! (Think about that like parent 
            object and respective children)!
            Let imagine that we have a lot of children (SObjects) and one parent 
            object. Also let for all these objects we have sub programs that 
            catch exit event. And now let our program gone to the end of code, 
            so program must quit and Perl must destroy and unload our program!
            However Errors module have job to do, it must call all subs that are 
            joined into 'exit' chain!
            See follow block:
            foreach $obj call {
            | SObject 1 | -> onExit sub
            | SObject 2 | -> onExit sub
            &#8230;
            | SObject n | -> onExit sub
            | Main object | -> onExit sub
            }

            Note: "main" handling sub is called after all sobject subs, so if 
            you catch onError event don't exit application in sobject routines, 
            becase all calls to next subs in chain will fail.

            All this will be happened with all other events/signals! So you have 
            to check reason and decide whether you must do anything into 
            respective sub! See simple example:
            sub anysub {
            my $obj = shift; # 'Errors' object
            my $err = shift; # Error number/message
            my $name = shift; # 'name' of error
            if($name =~ m/some/si)
             {
               $obj->print ("Error in some!");
             }
            else
             {
               $obj->print ("Error in ... I don't know :-)!!!");
             }
            }
            If name is 'some' we can do something, but when the error is 
            somewhere else you may want to miss it! You have to decide!

            To delete SObject call:
            $obj->detach('some');
            To uninstall event/signal:
            $obj->uninstall('onError','some'); # for some SObject
            or
            $obj->uninstall('onError'); # for main object

            At the end I would like to notice that this module was originally 
            written for Web and more correct for WebTools Perl sub system (look 
            at http://www.proscriptum.com/)
            So to allow Errors object to let know, whether content type is sent 
            use follow line:
            $obj->content($state); # $state can be '1' - yes and '0' - is not 
            sent yet!
            If you want to send default content (HTTP) header use:
            $obj->header();
            Note: If $obj->content() is '1' then $obj->header() will return 
            immediately without printing default header, but if you are not 
            still sent header (or if you forgot to tell that to Error object via 
            $obj->content(1) ) then $obj->header() will sent default header.
            To overwrite default header function use statement bellow:
            $obj->install('header',\&your_header_sub);
            All this (header and content functions) is needful because if this 
            script is WEB based and error occurred you may want to print some 
            text into browser, but if you forgot to print content, error will 
            occurred (Internal Error). And vice versa: If content is already 
            sent and you print it again then second content header will appear 
            in browser.
            For more information, look at Errors::Errors module.


      www.proscriptum.com is property of Julian Lishev. 
      All rights reserved, Sofia 2001-2003. 