pffan239 has asked for the wisdom of the Perl Monks concerning the following question:

Esteemed Monks,

I've got a CGI::Application based program that uses CGI::Application::Plugin::Session (which is basically a wrapper on CGI::Session) to handle the session stuff.

Recently, I wanted to change from the default encoding in mysql to UTF-8. Easy enough, just issue:

$dbh->do(qq|set names 'utf8'|);

right after the new'ng up the database handle, right?

For reasons unclear to me, this causes some craziness over in CGI::Session. Here's the error that it generates:

Error executing class callback in prerun stage: Can't locate object method "errstr" via package "CGI::Session::Serialize::storable" at /usr/lib/perl5/site_perl/5.8.6/CGI/Session.pm line 674.

Things go back to working fine if I take that line out.

I've checked to make sure that the mysql database is UTF-8 (and tables too), on the off chance that would make a difference. I also blew away any old sessions in case it might have had a problem with old data in the old character set.

Anybody have any ideas on what might be going on?

Thanks for any help you can provide!

Replies are listed 'Best First'.
Re: CGI::Session and UTF-8 with Mysql?
by Joost (Canon) on Jul 27, 2007 at 14:13 UTC
Re: CGI::Session and UTF-8 with Mysql?
by Corion (Patriarch) on Jul 27, 2007 at 13:58 UTC

    I guess your SQL raises an error that you never ask for. I suggest you initialize your database connection via

    my $dbh = DBI->connect(..., {RaiseError => 1});

    that way, your program will die whenever it encounters an SQL error. Alternatively, you could check for errors in your SQL by modifying your code to:

    $dbh->do(qq|set names 'utf8'|) or die "Could't set names to utf8: " . $dbh->errstr;

    but it can be hard to track down every unguarded usage of a DBI method. (As an aside, maybe a DBI::fatal would be useful here). Your unguarded usage of $dbh->do leaves the errstr value in it and then triggers a bug in CGI::Session, which seems to always assume that it can treat any serializer like a DBI / dbh / sth object, but obviously the ::storable subclass doesn't behave like a DBI class.

    You might want to raise a bug report with the CGI::Session maintainer(s), as I find many calls to ->errstr scattered throughout the code, so I guess that part of the code was never tested against the ::storable serializer.

      re: DBI error handling, I left it out of my example code snippet, but I tested with using the "or die" idiom you showed.

      However, it doesn't fire off the die. Strangely, that statement seems to work just fine. It just taints in the $dbh in some way I can't put my finger on yet.

      For what its worth, in terms of a more global error handling scheme for DBI I find the die's of RaiseError to be a little too drastic. Instead, I wire in my own error handling scheme, ie:

      $dbh->{'HandleError'}=\&dbierror;

      re: Possible CGI::Session bug, I scanned the modules RT queue and noted another utf8 related problem that's still open. Maybe I can help push along its resolution...

      Thanks for your input!