Open yorkshire-pudding opened 1 year ago
Thanks for reporting, @yorkshire-pudding. This is a strange error that I've never seen before.
Entity Plus is like a mini-core for entities. Often the errors you get are produced in other places, but since a lot of the
"traffic" goes through Entity Plus, you only see the E+ error. The error you saw is produced when checking the entity controller
definition of an entity - presumably a custom entity provided by a contrib module. So, this is probably some weird combination of factors that prevents the info to have an entity controller
- perhaps an issue with cached information. The fact that things got "fixed" once you ran 7.4 may indicate an issue with a contrib module that's not compliant with 8.1 and fails to initialize their entity info... in specific situations.
If you want to troubleshoot this, we'll need all the errors (including anything that happened before the one you posted), as well as a list of contrib modules in your site.
class_implements($info['controller class'])
is returning FALSE
, so that should be added as another condition in line 280 to avoid the fatal error, which might or might not mask the actual cause, but would certainly avoid unnecessarily taking down the site.
I've had the issue again and switched to PHP 7.4 straight away and it fixed. Only happening on certain pages with 8.1 so time to test locally and see if I can get some useful Krumo backtraces
Also got warning:
Warning: class_implements(): Class MatchRedirectEntityController does not exist and could not be loaded in entity_plus_theme() (line 994 of /app/docroot/modules/contrib/entity_plus/entity_plus.module).
Tracked it down. Match Redirect module is causing it. As this is not essential to the site (was using it to redirect bots looking for Wordpress pages to a custom page) I can disable without causing any issues until this is resolved. I have transferred log details to an issue there, but if you have any insights on what is going on there, then might be helpful; looking at the module it looks like the class MatchRedirectEntityController
does exist and is referenced in `hook_autoload_info, but perhaps I'm missing something.
https://github.com/backdrop-contrib/match_redirect/blob/89836b662351c8eef4cf90922f64e216010cd0ed/match_redirect.module#L26-L35
@yorkshire-pudding thanks for including the backtrace. I'm looking at it, and there are some clues of what's going on there.
First, this whole chain of events is happening because of an earlier "custom PHP error" (see line 12 in the backtrace), that triggers a "fallback" to maintenance mode. You can see that in number 10 in the backtrace (the lower you go in that backtrace, the further from "now" you are). When backdrop tries to theme the error, to do that it has to reinitialize the whole theme registry, which is not cached for some reason (see number 6). The problem is that, when you are in maintenance mode, that include file with MatchRedirectEntityController
is not loaded, which triggers the fatal error. Apparently, the autoload hooks are not run when in maintenance mode - need to verify that's the case.
It would be helpful to check your log to see if there are any other errors logged in before the fatal one - that can offer clues to what was the initial error that unleashed the whole series of events.
Ultimately, perhaps a good stopgap measure would be for entity_plus_theme()
to check if we are in maintenance mode before returning the theme information. My concern with that is that this info is cached, and while it may prevent the fatal, it may create issues down the road with that incomplete cached theme registry.
So, in the end, while disabling Match Redirect may help, ideally we need to find where the original uncaught PHP error. occurred.
I'll try to come up with a way for you to temporarily patch Entity Plus in php 8.1 so that you can try to reproduce the error. Once patched, we may be able to see what the original error was. More later
Hmmm... some of my logic above may not be correct - not sure if we are in maintenance mode. _backdrop_log_error()
themes the error as if it was in maintenance mode, but the site is not put in MM. However, the rest may all be true. Please check the dblog thoroughly for earlier errors. And you say this is happening when running database update?
I'll try to see what other errors could be related. Just to clarify though:
And you say this is happening when running database update?
No - it happened first updating a node. That node has entity reference fields, data, embedded youtube but nothing particularly special. After it happened there it then happened on nearly every page load until I fixed it. Then after putting it back to PHP 8.1 it behaved mostly until I tried updating a node again.
Got this when accessing status report:
Warning: class_implements(): Class MatchRedirectEntityController does not exist and could not be loaded in entity_plus_crud_get_info() (line 180 of /home/username/website/production/docroot/modules/contrib/entity_plus/entity_plus.module).
Also got this odd error:
Error: Cannot use object of type stdClass as array in system_page_delivery_callback_alter() (line 1136 of /home/username/website/production/docroot/core/modules/system/system.module).
but the calling URL is https://www.domain.tld/apple-touch-icon.png
The header very clearly says:
<link rel="apple-touch-icon" sizes="180x180" href="/files/favicons/apple-touch-icon.png"/>
( I use responsive favicons module to handle these)
Thanks for the additional info. All of these logs point out at an initial error that triggers the whole chain reaction that ends with the E+ fatal. The first function in the chain is always _backdrop_exception_handler()
In order to find out what is producing this error, please try the following manual patches:
Line 180 of entity_plus.module
if (isset($info['controller class']) && class_exists($info['controller class']) && in_array('EntityPlusControllerInterface', class_implements($info['controller class']))) {
Line 994 of the same:
if (isset($info['controller class']) && class_exists($info['controller class']) && in_array('EntityPlusControllerInterface', class_implements($info['controller class']))) {
Then, using PHP 8.1, edit that node once again to trigger the initial error. Supposedly, the patches above will prevent E+ from crashing (they may produce other problems, though). The crashing happens because those E+ functions are being called at a time when autoload hooks haven't yet run.
So, the above should hopefully reveal what the original error is that's triggering all of this.
(Fixed a typo in the above)
Shoot. More typos! Let me fix those before you patch.
And presume I should re-enable match_redirect, right?
OK, done.
Yes, get the site to the state where it was when it crashed.
Must have been something else as well as it will not recreate the error 😕
Can you check the dblog for the most recent messages after you've updated the node?
Also, clear caches, update node again, save, clear caches again? Then check dblog.
Nothing there at all either before or after clearing caches. 😕
Hmm... the other odd error you included there:
Error: Cannot use object of type stdClass as array in system_page_delivery_callback_alter() (line 1136 of /home/username/website/production/docroot/core/modules/system/system.module).
This is strange, and may be the originating error that triggered the whole thing - but obviously hard to reproduce. Somehow, the variable $page_callback_result
passed to the hook implementation system_page_delivery_callback_alter()
is an object instead of a string. This may be produced by one of the contrib modules in the site. If you have the time - could you include the list of contrib modules you are using?
Otherwise, that manual patch should prevent the fatal error for now. Keep an eye on the dblog for other errors, esp, the one above.
One common thing in all the backtraces you posted: they ALL happen in relation to maintenance mode. Can you try putting your site in maintenance mode and editing that node once again?
No difference with maintenance mode:
Got more errors when running bee config-import
even though there was no config update for match_redirect
class_implements(): Class MatchRedirectEntityController does not exist and could not be loaded
/home/stocksfieldbapti/website/production/docroot/modules/contrib/entity_plus/entity_plus.module:281
in_array() expects parameter 2 to be array, bool given
/home/stocksfieldbapti/website/production/docroot/modules/contrib/entity_plus/entity_plus.module:281
class_implements(): Class MatchRedirectEntityController does not exist and could not be loaded
/home/stocksfieldbapti/website/production/docroot/modules/contrib/entity_plus/entity_plus.module:281
in_array() expects parameter 2 to be array, bool given
/home/stocksfieldbapti/website/production/docroot/modules/contrib/entity_plus/entity_plus.module:281
class_implements(): Class MatchRedirectEntityController does not exist and could not be loaded
/home/stocksfieldbapti/website/production/docroot/modules/contrib/entity_plus/entity_plus.module:262
in_array() expects parameter 2 to be array, bool given
/home/stocksfieldbapti/website/production/docroot/modules/contrib/entity_plus/entity_plus.module:262
I did raise this issue quite some time ago so probably all related
@yorkshire-pudding those spots can be temporarily fixed the same way I mentioned above - add class_exists($info['controller class'])
as the second statement in those if.
It's the same issue: those functions are running before the autoload hooks have run - for an unknown reason.
@yorkshire-pudding - question: do you have the Drupal compatibility layer enabled? I see match_redirect still uses some drupal namespaced functions - in hook_init, which may not be caught.
@yorkshire-pudding - question: do you have the Drupal compatibility layer enabled? I see match_redirect still uses some drupal namespaced functions - in hook_init, which may not be caught.
I do have drupal compatibility switched on for that site; checked both locally and on host.
@yorkshire-pudding those spots can be temporarily fixed the same way I mentioned above - add
class_exists($info['controller class'])
as the second statement in those if.It's the same issue: those functions are running before the autoload hooks have run - for an unknown reason.
That was with the patch you suggested (it is the same site). The git pull happens before the config-import
That was with the patch you suggested (it is the same site). The git pull happens before the config-import
No, no. You fixed those other lines. I meant: you need to fix these NEW lines with the same patch.(281 and 262).
That was with the patch you suggested (it is the same site). The git pull happens before the config-import
No, no. You fixed those other lines. I meant: you need to fix these NEW lines with the same patch.(281 and 262).
Thanks. patching those lines too enables config-import to work
I've had a site on PHP 8.1 for a while with no problem. Yesterday on mobile, I updated a field on a node and saved. Wasn't showing in view to attempted to flush caches.
Site went 500 for logged in users whilst could still load front end, but eventually front end went as well (presumably when cache expired). When I got a minute, I went on and tried a few things to fix.
Tried clearing caches with bee and got this error:
Put in maintenance mode with bee
Deleted the entity_plus directory and re-downloaded (so latest version) with bee (no disabling or uninstalling - too many dependencies). No change I then tried PHP 8.0 - same. Then tried PHP 7.4 and site worked. This site had been a bit neglected (not any security updates) and there were a few updates. I did those updates in GUI (including core) and was fine. I then tried putting it back to PHP 8.1 and everything was fine again.
I'm reluctant to call it a bug as I have no idea of steps to reproduce. It could be a combination of things and I don't want to try and reproduce. I just wanted to put this here in case this bit of code could be improved to prevent this happening again if conditions give this function the wrong type again?