Problem/Motivation
Having this error after updating to Drupal 9.1.0 -- am using PHP 7.4.11
( ! ) Fatal error: Uncaught Error: Call to a member function prepare() on null in D:\wamp64\www\workbench\workbench_d9_test1\core\lib\Drupal\Core\Database\StatementWrapper.php on line 49
( ! ) Error: Call to a member function prepare() on null in D:\wamp64\www\workbench\workbench_d9_test1\core\lib\Drupal\Core\Database\StatementWrapper.php on line 49
Call Stack
# Time Memory Function Location
1 0.9146 44434200 Drupal\business_rules\Util\BusinessRulesProcessor->__destruct( ) ...\BusinessRulesProcessor.php:0
2 0.9146 44434200 Drupal\Core\KeyValueStore\DatabaseStorageExpirable->deleteAll( ) ...\BusinessRulesProcessor.php:766
3 0.9147 44435904 Drupal\Core\Database\Query\Delete->execute( ) ...\DatabaseStorage.php:241
4 0.9148 44436528 Drupal\Core\Database\Driver\mysql\Connection->query( ) ...\Delete.php:55
5 0.9148 44436528 Drupal\Core\Database\Driver\mysql\Connection->query( ) ...\Connection.php:88
6 0.9148 44437008 Drupal\Core\Database\Driver\mysql\Connection->prepareStatement( ) ...\Connection.php:822
7 0.9148 44437232 Drupal\Core\Database\StatementWrapper->__construct( ) ...\Connection.php:557
Steps to reproduce
At this point, run any automated test.
Proposed resolution
To be determined.
Remaining tasks
To be determined.
User interface changes
To be determined.
API changes
To be determined.
Data model changes
To be determined.
Comments
Comment #2
bmustafa commentedComment #3
tbcanHi There,
I checked I saw that the problem is Replace \Drupal\Core\Database\Connection::destroy() with a proper destructor
If I comment out of changed of
then the problem is gone away.
Comment #4
nwom commentedThank you. Commenting out the following line in
core/lib/Drupal/Core/Database/Driver/mysql/Connection.phpdefinitely temporarily resolved the issue:parent::__destruct();Comment #5
justin.dasilva commentedI'm seeing a similar error recently:
Fatal error: Uncaught Error: Call to a member function prepare() on null in /drupal/web/core/lib/Drupal/Core/Database/StatementWrapper.php:49 Stack trace: #0I notice this error when I enable a certain module that has scss files defined in the libraries.yml
Is a fix for this issue coming soon?
Comment #6
lolandese commentedThe same happens on Postgres. No workaround as in #4 found yet.
Comment #7
colanThe 8.x-1.x branch doesn't support D9. Is this still a problem on 2.x?
Note: You'll probably run into #3199227: Composer fails due to missing D9 version of module "dBug for Drupal" first.
Comment #8
nwom commented@colan: Yes this still happens on the newest 2.x-dev version.
Comment #9
colan👍
Comment #10
colanNow that I got the tests running, you can see it in the testbot results.
Comment #11
bmustafa commentedi am cross referencing this issue::
https://www.drupal.org/project/drupal/issues/3201898#comment-14022400
Comment #12
colanAnd this time with d.o markup for readability & more info: #3201898-3: Error: Call to a member function prepare() on null after updating to Drupal 9.1.0 / PHP 7.4.11
Comment #13
bmustafa commentedThanks colan for the markup tips - first time i see this useful link.
Comment #14
joelseguinI can confirm the issue with D9 as well. #4 did fix the issue for me, but obviously it's not a long term-solution. I'll be available to test any patches/udpates that are available to validate. I'm using Business Rules on a freshly migrated D9 site.
Comment #15
mparker17While working on #3040253-34: Add AJAX support to Paragraphs (branch
2.x), I was seeing...... which was preventing tests from finishing successfully. This is a slightly different message than what has been reported in this issue thus far; but I believe is related because I was able to track this down to the same piece of code, i.e.:
\Drupal\business_rules\Util\BusinessRulesProcessor::__destruct().***
In my case, I was able to "fix" the problem by commenting out the
$keyvalue->deleteAll();line in the desctructor... (WARNING: do not do this: it was found to be a Really Bad Idea in comment #17) ... this at least lets my tests pass; but I think this is the wrong solution; i.e.: will commenting out this line causekey_value_expireto grow without constraints, like #2931611-11: Honeypot key value entries never expire (effectively)?Comment #16
mparker17Not much on why this is happening from a historical context...
This code appears to have been added in commit
1bcf53dby @yuriseki on Sat Apr 8 02:27:09 2017 -0300 (with the commit message "Revision 1"); but its not clear from the commit message, or the context in the commit, why the line was added, or what it does, or what would happen if we removed it.Comment #17
mparker17Recall the code in question is...
$this->util->getKeyValueExpirable('process')translates to\Drupal\Core\KeyValueStore\KeyValueDatabaseExpirableFactory::get('business_rules.' . 'process'). The docs describe this function as "constructs a new expirable key/value store for a given collection name" It returns a\Drupal\Core\KeyValueStore\DatabaseStorageExpirable.. The line where the error appears callsdeleteAll()(described as "deletes all items from the key/value store") on the returned object, i.e.:\Drupal\Core\KeyValueStore\DatabaseStorageExpirable::deleteAll()(inherited from\Drupal\Core\KeyValueStore\DatabaseStorage::deleteAll()).It looks like
$this->util->getKeyValueExpirable('process')is also called in\Drupal\business_rules\Util\BusinessRulesProcessor::avoidInfiniteLoop. That function provides more context: it looks as if the items in$this->util->getKeyValueExpirable('process')are being used as some sort of semaphore to prevent, say, an event from triggering another event triggering the first event, etc.If these are being saved to the database then they definitely need to be cleaned up afterwards (i.e.: do NOT comment out
$keyvalue->deleteAll();on a real database - I will update my earlier comment with a warning). So we'll have to figure out a way to do that which doesn't cause errors in__destruct().That being said, it seems like storing this stuff in the database could cause two requests happening simultaneously (i.e.: by two different users) could interfere with each-other in an undesirable way... i.e.: user A could cause infinite loops for user B if user A's __destruct() method cleared user B's items in the
key_value_expiretable (which seems likely as I see no way to differentiate between requests). So there may be a deeper bug here.Comment #18
mparker17I think at this point, this is a duplicate of #3133687: Wrap keyvalue delete in BusinessRulesProcessor destruct
Comment #19
mparker17Added issue reference.
Comment #20
mparker17Acutally, this is not a duplicate of 3133687!
Comment #21
colanBut it looks like it might go away with the refactoring in #3202612: Change BusinessRulesProcessor's to cache event data to memory, not the database. So let's wait for that.
Comment #22
bmustafa commentedThe issue is still exhibited in the freshly released "2.0.0-alpha2"
hope that #3202612 might fix it.
Comment #23
mparker17A patch is ready for review in #3202612-17: Change BusinessRulesProcessor's to cache event data to memory, not the database - @joelseguin, @NWOM, @lolandese, @justin.dasilva, and @tbcan, if you could review the code, test the patch, and provide any feedback on the patch in that issue, it would be greatly appreciated and would help move both issues forward!
Comment #24
bmustafa commentedi confirm #3202612-17 has resolved the issue for me.
Comment #25
joelseguin@mparker17
Patch #3202612-17 seems to do the trick for me as well. I updated to the latest 2.x-dev then applied the patch without issues. I've tested locally and on our dev server. My simple business rule is running fine and I am no longer getting errors.
Comment #26
colan