A sticky problem facing any further potential refactorings is the error handling.
Basically the current methodology, of return values checked by caller, is not used consistently. In some cases methods redirect to oops pages from way down in the depths, making it really hard to work out how to recover, and makes changing the code a dicey business.
While I'm not a fan of adding another required module, I think it would be a good idea to add a sensible exception handling module. Perl 6 is destined to have compatible syntax with Error.pm, so this would seem to be the sensible choice.
Note that while we
could use simple eval/die, the problems of generating a sensible exception object, and a usable stack trace, remain. Error.pm has already done that.
Using Error.pm would allow us to write (for example):
use Error qw(:try);
try {
# and somewhere in the depths of the call stack below.....
throw OopsException( "Permission denied" );
}
catch OopsException with {
my $ex = shift; # Get hold of the exception object
print TWiki::redirect( ... $ex->message)() ... );
return.
}
All in all, much
much cleaner and safer than the current approach.
I'd be interested to hear what the perl experts think.
--
CrawfordCurrie - 16 Oct 2004
I have been using Error.pm for years in combination with
Exception:Class
. The advantage is easy creation of exception classes (with custom fields, according to what needs capturing in given context), and on the top of that,
Devel::StackTrace
, stack trace that i find more usable then one produced by Carp::longmess (used by Error.pm).
package:TWiki::Exceptions
# defined exception classes
use Exception::Class ( TWiki::Exception::Authenticate =>
{
description => 'authentication exception',
fields => [ 'some_context_field' ]
},
TWiki::Exception::Storage =>
{
description => 'storage exception',
fields => [ 'some_context_field' ]
},
);
Then in another place, to use it:
use TWiki::Exceptions;
use Error qw(:try);
# hack to use the Exception::Class::Base instead of Error::Simple
# when using try/catch from Error.pm
push @Exception::Class::Base::ISA, 'Error';
try {
# and somewhere in the depths of the call stack below.....
throw TWiki::Exception::Authenticate( error=>"Permission denied", show_trace=>1 );
}
catch TWiki::Exception::Authenticate with {
my $ex = shift; # Get hold of the exception object
print TWiki::redirect( ... $ex->message)() ... );
return.
}
catch Error with {
# will catch any error (remaing from those caught above)
...
}
Given the size of TWiki today, and its fast development, this approach gives more fine grained expcetion handling.
--
ToniPrug - 12 Nov 2004
Hmmmm. I like the sound of that, but I'm not sure we
want fine-grained exceptions. Many of the developers of TWiki have historically had problems with simple OO concepts, and fine-grained exception classes are likely to blow some minds. It might be better (at least initially) to restrict the use of exceptions to a small number of very well defined cases (system errors, authentication exceptions, and redirects) using Error::Simple only.
--
CrawfordCurrie - 28 Nov 2004
We're now using Error.pm in
DevelopBranch, though with our own simple exception classes based on
Error::Simple.
--
CrawfordCurrie - 22 Feb 2005
The version of Error.pm which is used in TWiki's
SVN and Beta distributions is not the
CPAN version: It has been modified to spit out additional lines to STDERR. So don't be surprised if you have extra lines in your web servers error log or if your unit tests create more than just the success report even if all tests are OK.
--
HaraldJoerg - 14 Nov 2005