perlquestion
jeffa
I have a module that is effectively a wrapper for DBI - when you call it's constructor (new), you pass the same arguments you would to DBI::connect(). The problem i am having is getting the module to <u>carp</u> errors back to the client without giving away the line number from the module itself. For example, given some wrapper named Foo and trying to connect to a non-existant server, i would like for the following error:
<pre>
DBI->connect(mysql:host) failed: Unknown MySQL Server Host 'host' (2)
at Foo.pm line 13
at ./foo.pl line 11
</pre>
to only list ./foo.pl, the client that called the module.
<p>
Now, philosophical question: if this really should be desired behavior and left alone, then i am all for that. But, if there is a way to implement what i'd like, then i would sure appreciate a nudge in the right direction. My reasoning is that such errors should not accidentaly lead a user into the source code of the module, because it is a '<font color="red">red herring</font>'. By even mentioning the originating line of code from the wrapper module, a user might just be tempted to think the 'module is broken.' (I also have an appreciation for debugging as well, and would like to leave that door open.)
<p>
Here is what i have been working with so far:
<readmore>
<code>
package Foo;
use DBI;
use Carp;
use strict;
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
# THE PROBLEM:
$self->{'dbh'} = DBI->connect(@_) or carp;
return $self;
}
1;
</code>
I did try wrapping the instantiation in an eval block:
<code>
# THE SAME PROBLEM:
eval {
$self->{'dbh'} = DBI->connect(@_,{RaiseError=>1,PrintError=>0})
};
carp $@ if $@;
</code>
... but the results were exactly the same. An evil thought did cross my mind at this point - substitute the module line number(s) out ... but that surely is not 'The Right Way'.
<p>
And here is the client which calls the wrapper with bad credentials to generate the errors. It also uses DBI in the same manner as the 'control subject':
<code>
use strict;
use Foo;
use DBI;
print "Comparing wrapper:\n";
my $foo = Foo->new(qw(DBI:mysql:mysql:host user pass));
print "\nComparing DBI:\n";
my $dbh = DBI->connect(qw(DBI:mysql:mysql:host user pass));
</code>
What i would like is to only show that the error orginated
from the client and not the module ... just like DBI
reports:
<pre>
DBI->connect(mysql:host) failed: Unknown MySQL Server Host 'host' (2)
at ./foo.pl line 14
</pre>
Thanks!
<p>jeffa</p>
<font size=1>
<pre>
L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
B--B--B--B--B--B--B--B--
H---H---H---H---H---H---
(<a href="http://jeffa.perlmonk.org/tripdid.mp3">the triplet paradiddle with high-hat</a>)
</pre></font>