package OpenInteract::Error; # $Id: Error.pm,v 1.6 2002/01/02 02:43:53 lachoy Exp $ use strict; $OpenInteract::Error::VERSION = sprintf("%d.%02d", q$Revision: 1.6 $ =~ /(\d+)\.(\d+)/); use constant DEBUG => 0; # Collection of error tracking variables -- look ma, no 'use vars'! $OpenInteract::Error::user_msg = undef; $OpenInteract::Error::system_msg = undef; $OpenInteract::Error::type = undef; $OpenInteract::Error::package = undef; $OpenInteract::Error::filename = undef; $OpenInteract::Error::line = undef; $OpenInteract::Error::method = undef; $OpenInteract::Error::extra = (); $OpenInteract::Error::notes = undef; sub clear { $OpenInteract::Error::user_msg = undef; $OpenInteract::Error::system_msg = undef; $OpenInteract::Error::type = undef; $OpenInteract::Error::package = undef; $OpenInteract::Error::filename = undef; $OpenInteract::Error::line = undef; $OpenInteract::Error::method = undef; $OpenInteract::Error::extra = {}; $OpenInteract::Error::notes = undef; } # Retrieve all the package variables in a hashref sub get { my ( $class ) = @_; return { user_msg => $OpenInteract::Error::user_msg, system_msg => $OpenInteract::Error::system_msg, type => $OpenInteract::Error::type, package => $OpenInteract::Error::package, filename => $OpenInteract::Error::filename, line => $OpenInteract::Error::line, method => $OpenInteract::Error::method, extra => $OpenInteract::Error::extra, notes => $OpenInteract::Error::notes }; } # Set all package variables sub set { my ( $class, $p ) = @_; no strict 'refs'; # First clean everything up so there's nothing # hanging around from a previous error OpenInteract::Error->clear; # Then set everything passed in foreach my $key ( keys %{ $p } ) { warn "OpenInteractI::Error::set >> Setting error $key to $p->{ $key }\n" if ( DEBUG ); ${ 'OpenInteract::Error::' . $key } = $p->{ $key }; } # Set the caller information if the user didn't pass # anything in unless ( $p->{package} and $p->{filename} and $p->{line} ) { ( $OpenInteract::Error::package, $OpenInteract::Error::filename, $OpenInteract::Error::line ) = caller; } return OpenInteract::Error->get; } # Class method -- really we just collect the caller info and # send it over to the error object... sub throw { my ( $class, $p ) = @_; my $R = OpenInteract::Request->instance; unless ( $p->{package} and $p->{filename} and $p->{line} ) { my ( $cpkg, $cfile, $cline ) = caller; $p->{package} = $cpkg; $p->{filename} = $cfile; $p->{line} = $cline; } my $error_obj_class = $R->CONFIG->{error}{error_object_class} || $R->CONFIG->{error_object_class}; return $error_obj_class->throw( $p ); } 1; __END__ =pod =head1 NAME OpenInteract::Error - Provide central holding location for Interact errors =head1 SYNOPSIS OpenInteract::Error->set( ... ); $R->throw( ... ); my $ei = OpenInteract::Error->get; print "Last error message: $ei->{system_msg}\n"; =head1 DESCRIPTION This class provides a central location for error messages from all Interact modules. The error information collected in these variables is guaranteed to result from the most recent error generated by Interact. =head1 VARIABLES All of these variables are package variables, so you refer to them like this: $OpenInteract::Error:: $OpenInteract::Error::system_msg See the L section below for hints on making the error variables shorter. B ($) A generic message that is suitable for showing a user. When telling a user something went wrong, you do not want to tell them: execute called with 2 bind variables when 1 are needed instead, you want to tell them: Database query failed to execute This variable is identical to the value thrown by the I command, so you do not normally need to refer to it. B ($) Even though you do not want to show your users details of the error, you still need to know them! The variable I gives you details regarding the error. B ($) Interact knows about a few types of errors. Some depend on your Interact implementation (e.g., DBI, dbm, LDAP, etc.). Others can be: =over 4 =item * security: There is a security violation and the action could not be completed. =item * config: There was a problem reading/writing configuration information. =back B ($) Set to the package from where the error was thrown. B ($) Set to the method from where the error was thrown. B ($) Set to the filename from where the error was thrown. B ($) Set to the line number from where the error was thrown. B (\%) Different Interact classes have different information related to the current request. For instance, DBI errors will typically fill the 'sql' and 'values' keys. Other Interact implementations may use different keys; see their documentation for details. =head1 METHODS B () Clears the current error saved in the class. Classes outside the B hierarchy should never need to call this. No return value. B Returns a hashref with all the currently set error values. B First clears the variables then sets them all in one fell swoop. The variables that are set are passed in the first argument, a hashref. (See L for the names and purposes.) Also sets both the package and method variables for you, although you can override by setting manually. No return value; B Throws an error from anywhere in the system. Kept for backward compatibility -- most of the time you will use: $R->throw( ... ); We simply pass the parameters (with any caller info) to the method by the same name in the error object class. =head1 NOTES Some people might find it easier to alias a local package variable to an OpenInteract error variable. For instance, you can do: *err_user_msg = \$OpenInteract::Error::user_msg; *err_system_msg = \$OpenInteract::Error::system_msg; *err_type = \$OpenInteract::Error::type; *err_extra = \%OpenInteract::Error::extra; And then refer to the alias in your local package: my $obj_list = eval { $obj->fetch_group( { where => 'this = that' } ) }; if ( $@ ) { warn "Error found! Error: $@\n", "Error type: $err_type\n", "More specific: $err_system_msg\n", "Extra stuff:\n", "--$err_extra{sql}\n", "--$err_extra{values}\n"; } =head1 TO DO Nothing known. =head1 BUGS None known. =head1 COPYRIGHT Copyright (c) 2001-2002 intes.net, inc.. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHORS Chris Winters =cut