Suddenly, out of the blue today, my web site is broken because of sessions problem. I have been using Dancer::Sessions::SQLite, something that I had coded, and that had worked just fine for months until today. Today I start getting the following error { "error" : "DBD::SQLite::st execute failed: constraint failed\nsessions.id may not be NULL at /usr/local/lib/perl5/site_perl/5.12.1/Dancer/Session/SQLite.pm line 159.\n" } The offending line is 142> sub flush { 143> my $self = shift; 144> 145> my $sth; 146> if (session_db($self->id)) { 147> $sth = $dbh->prepare(qq{ 148> UPDATE sessions 149> SET a_session = ? 150> WHERE id = ? 151> }); 152> } 153> else { 154> $sth = $dbh->prepare(qq{ 155> INSERT INTO sessions (a_session, id) 156> VALUES (?, ?) 157> }); 158> } 159> $sth->execute(Storable::freeze($self), $self->id); 160> 161> return $self; 162> } Seems like $self->id is not generating a session id. So, while I try and figure out what is going on, I thought I would switch to the factory-provided Dancer::Session::Storable. However, with that I get the following error { "error" : "Warning caught during route execution: Use of uninitialized value $id in concatenation (.) or string at /usr/local/lib/perl5/site_perl/5.12.1/Dancer/Session/Storable.pm line 57.\n" } The offending line is 55> sub session_file { 56> my ($id) = @_; 57> return path(setting('session_dir'), "session_$id.stor"); 58> } Hmmmm... once again, no $id. So, what is going on, and how do I fix this? The only thing new that I can think is that I upgraded to Dancer 1.3020 a couple of days ago. Although, I could have sworn that the web site was working fine even after upgrading, but I guess I should swear. Any help would be much appreciated.. this is a tight spot. Puneet.
On Friday 25 March 2011 03:51:49 Mr. Puneet Kishor wrote:
Seems like $self->id is not generating a session id. So, while I try and figure out what is going on, I thought I would switch to the factory-provided Dancer::Session::Storable. However, with that I get the following error
{ "error" : "Warning caught during route execution: Use of uninitialized value $id in concatenation (.) or string at /usr/local/lib/perl5/site_perl/5.12.1/Dancer/Session/Storable.pm line 57.\n" }
The offending line is
55> sub session_file { 56> my ($id) = @_; 57> return path(setting('session_dir'), "session_$id.stor"); 58> }
Hmmmm... once again, no $id.
Interesting. I'm looking in to this to see if I can reproduce it. I do notice that my flush() implementation in D::S::Storable uses $self->{id} rather than $self->id, which is wrong, so I'll fix that shortly. From the problems you're having with D::S::SQLite, though, it does seem that $self->id is emtpy when your flush() is called. By the way, are you planning to release Dancer::Session::SQLite to CPAN? That looks like something which would be beneficial to other users. If you don't have time, I'd be happy to adopt it and release it for you. Cheers Dave P -- David Precious <davidp@preshweb.co.uk> (bigpresh) http://www.preshweb.co.uk/ "Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)
On Friday 25 March 2011 10:24:36 David Precious wrote:
I do notice that my flush() implementation in D::S::Storable uses $self->{id} rather than $self->id, which is wrong, so I'll fix that shortly.
I've released D::S::Storable 0.03 with this fix - can you see if that solves the warning for you? Cheers! -- David Precious <davidp@preshweb.co.uk> (bigpresh) http://www.preshweb.co.uk/ "Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)
Hi Dave, On Mar 25, 2011, at 6:24 AM, David Precious wrote:
On Friday 25 March 2011 03:51:49 Mr. Puneet Kishor wrote:
Seems like $self->id is not generating a session id. So, while I try and figure out what is going on, I thought I would switch to the factory-provided Dancer::Session::Storable. However, with that I get the following error
{ "error" : "Warning caught during route execution: Use of uninitialized value $id in concatenation (.) or string at /usr/local/lib/perl5/site_perl/5.12.1/Dancer/Session/Storable.pm line 57.\n" }
The offending line is
55> sub session_file { 56> my ($id) = @_; 57> return path(setting('session_dir'), "session_$id.stor"); 58> }
Hmmmm... once again, no $id.
Interesting. I'm looking in to this to see if I can reproduce it.
I do notice that my flush() implementation in D::S::Storable uses $self->{id} rather than $self->id, which is wrong, so I'll fix that shortly.
Yes, I noticed that as well, however, that was not the source of the error for me, at least. I actually changed that to $self->id but the error was the same. Empty $self->id.
From the problems you're having with D::S::SQLite, though, it does seem that $self->id is emtpy when your flush() is called.
Indeed. My sense is that something has changed upstream re. the way the session id is generated. Which is why my DSSQLite has suddenly stopped working.
By the way, are you planning to release Dancer::Session::SQLite to CPAN? That looks like something which would be beneficial to other users.
If you don't have time, I'd be happy to adopt it and release it for you.
I am going to release it to CPAN. I have just sat on it all this while, but this is a good incentive to fix it and release it. The git repo is at https://github.com/punkish/Dancer--Session--SQLite
Cheers
Dave P
-- David Precious <davidp@preshweb.co.uk> (bigpresh) http://www.preshweb.co.uk/
"Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)
On Friday 25 March 2011 03:51:49 Mr. Puneet Kishor wrote:
Seems like $self->id is not generating a session id.
Ah, looking at Dancer::Session::Abstract, the ID is set when the init method gets called; you've overriden the init method in Dancer::Session::SQLite, so the init() method in D::S::Abstract won't get called. I think you need to add something like the following to your init() : $self->SUPER::init(@_); That will call init() from D::S::Abstract, which looks like: sub init { my ($self) = @_; $self->id(build_id()); } Cheers Dave P -- David Precious <davidp@preshweb.co.uk> (bigpresh) http://www.preshweb.co.uk/ "Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)
On Mar 25, 2011, at 6:27 AM, David Precious wrote:
On Friday 25 March 2011 03:51:49 Mr. Puneet Kishor wrote:
Seems like $self->id is not generating a session id.
Ah, looking at Dancer::Session::Abstract, the ID is set when the init method gets called; you've overriden the init method in Dancer::Session::SQLite, so the init() method in D::S::Abstract won't get called.
Well, this wasn't the problem all this time, literally months (I started my github repo for this module in Aug, 2010, and the module has worked just fine until two days ago). How come it started to be a problem a couple of days back? If you note from the repo at [https://github.com/punkish/Dancer--Session--SQLite], the session is generated not via init, but via create. See below sub create { my ($class) = @_; my $self = Dancer::Session::Storable->new; $self->flush; return $self; } init simply sets up the db connection (or check that the session dir exists, in the case of file based session backends). Nevertheless...
I think you need to add something like the following to your init() :
$self->SUPER::init(@_);
I added the above to create(), not to init(), so create() now looks like so sub create { my ($class) = @_; my $self = Dancer::Session::SQLite->new; **** new line **** $self->SUPER::init(@_); $self->flush; return $self; } Yes, now the session id is generated, and things work as before. But, is this the correct fix? I am looking at your DSStorable for the pattern, and you have no such session SUPER::init() method in there.
That will call init() from D::S::Abstract, which looks like:
sub init { my ($self) = @_; $self->id(build_id()); }
Cheers
Dave P
-- David Precious <davidp@preshweb.co.uk> (bigpresh) http://www.preshweb.co.uk/
"Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)
On Friday 25 March 2011 12:22:35 Mr. Puneet Kishor wrote:
I added the above to create(), not to init(), so create() now looks like so
[...]
Yes, now the session id is generated, and things work as before. But, is this the correct fix? I am looking at your DSStorable for the pattern, and you have no such session SUPER::init() method in there.
I'm pretty sure you want it to be in your init() method. init() is called when the session engine is initialised. As for D::S::Storable, its init() method starts with: sub init { my ($class) = @_; $class->SUPER::init(@_); Cheers Dave P -- David Precious <davidp@preshweb.co.uk> (bigpresh) http://www.preshweb.co.uk/ "Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)
On Mar 25, 2011, at 8:32 AM, David Precious wrote:
On Friday 25 March 2011 12:22:35 Mr. Puneet Kishor wrote:
I added the above to create(), not to init(), so create() now looks like so
[...]
Yes, now the session id is generated, and things work as before. But, is this the correct fix? I am looking at your DSStorable for the pattern, and you have no such session SUPER::init() method in there.
I'm pretty sure you want it to be in your init() method. init() is called when the session engine is initialised.
As for D::S::Storable, its init() method starts with:
sub init { my ($class) = @_;
$class->SUPER::init(@_);
Interesting. The above must have changed in DSStorable version 0.02. I still have version 0.01, which is what I used as a pattern for DSSQLite. So, now I have added the above to my module, and yes, it works now. Again, the strange mystery is that this has worked for 7 months until a couple of days ago (actually, I first noticed this last night, so it was working fine until the day before). Oh well. Ok, I will test out DSSQLite once again, add more docs to it, and then release it on CPAN. Many thanks,
Cheers
Dave P
-- David Precious <davidp@preshweb.co.uk> (bigpresh) http://www.preshweb.co.uk/
"Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)
participants (2)
-
David Precious -
Mr. Puneet Kishor