-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
Fix crash on PHP 8.3 when a file is missing #20358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #20358 +/- ##
=========================================
Coverage 64.85% 64.85%
- Complexity 11445 11446 +1
=========================================
Files 431 431
Lines 37208 37208
=========================================
Hits 24132 24132
Misses 13076 13076 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
How does the crash looks like? Stacktrace? |
Error:
|
@@ -110,7 +110,7 @@ protected function getValue($key) | |||
{ | |||
$cacheFile = $this->getCacheFile($key); | |||
|
|||
if (@filemtime($cacheFile) > time()) { | |||
if (file_exists($cacheFile) && @filemtime($cacheFile) > time()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a bit weird, cause @
should've suppressed the error. Any idea why it doesn't work?
Introducing file_exists
make the operation non-atomic which isn't great if we're talking about cache.
A more universal way would've been something like how it is done in Yii3...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked into the issue a bit deeper. In my Craft CMS setup, I had DEV_MODE=true
enabled. In this mode, a PHP Warning interrupts program execution just like a PHP Error. So, the problem with the missing cache file must be happening at a different level.
Could you clarify what exactly makes the cache file operations non-atomic in this case? Yes, there are now two file operations: checking if the file exists and checking its modification time. But isn’t that the whole point of this method? First, verify the file exists, and only if it does, check its modification time. With the double check, we’d simply exit at the first step if the file isn’t there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you first check if file exist, and then read mtime from it, this means that file could be deleted by other process between these two operations. So file_exists
doesn't completely protect you from such errors, it only makes them appear much less frequently (at the cost of additional call, which is not necessary in 99.99% setups).
Warning As per code yii\base\ErrorHandler::handleError
So the handleError will show error page at the end for PHP ver >= 8.0.0 for example:
|
|
I'm not sure, maybe because my error_level still contain E_WARNING
But I tried the simple test on 8.2, it is shown the error
|
This fixes a problem I had after migrating Craft CMS (based on Yii2) to PHP 8.3