On our platform, users may have different combinations of products in their inventory. Every now and then, a user will report to us that the page that lists these products is crashing. What this "crashing" actually is is PHP just stoping the rendering of a product for no reason at all, and then not rendering the rest of the page (for example, PHP won’t include the footer file, so the page just ends at the half-rendered product).
Sometimes it stops at a random product after rendering it fully, sometimes it only renders a product’s image and stops the whole page rendering there.
Seemingly random changes to the code seem to make the crashing stop. What do I mean?
If I add this anywhere inside the product loop:
<?php echo "<script>console.log('test');</script>"; ?>
It will stop the error. Just today I decided turning php.ini’s display errors on and that fixed the error for some dude. Turning it off brought it back. Some other user was fixed when I changed the loop’s syntax from
<?php foreach ($inventory as $code) : ?>
to
<?php
foreach ($inventory as $code)
{
This is the current code for the loop:
<div class="myProductsList">
<?php
$inventory = GetUserInventory($user, $plan);
if ($inventory)
{
$evenOdd = false;
foreach ($inventory as $code)
{
$product = GetProductObject($code, $plan);
$product = $product[0]->ID;
if ($product)
{
$prdTitle = get_the_title($product);
$prdDate = get_the_date('F, Y', $product);
$prdImg = get_the_post_thumbnail_url($product);
$prdLink = str_replace('/offer/', '/product/', get_the_permalink($product));
$evenOdd = !$evenOdd;
$tagCloud = get_field("prd_tagcloud", $product);
$owner = false;
include 'parts/product-card.php';
}
}
}
?>
</div>
And this is the current code for the product-card
<div class="productCard altCard_<?=$evenOdd;?> <?=$owner;?>" stamp="<?=get_the_date('U', $product);?>">
<div class="productCardCont fullw fullh cont col">
<a href="<?=$prdLink;?>">
<img class="fullw" src="<?=$prdImg;?>">
</a>
<div class="productCardAbout fullw hcent cont col npad">
<h3 class="fullw fcent"><?=$prdTitle;?></h3>
<span class="fullw fcent"><?=$prdDate;?></span>
<div class="productCardWarp"></div>
<div class="ctaMain cont col hcent" id="#ctaMain">
<?=ctaMain($prdLink, "Select");?>
</div>
</div>
<span style="display:none!important;"><?=$tagCloud;?></span>
</div>
</div>
I have absoulutely no idea what causes this, especially since no errors appear when I turn them on, no product has any invalid or corrupted data (as you can see I only pull their images, names and date), no inventory code is ever wrong, we have very few users compared to our VM’s specs capabilities, the page always loads blazing fast, and as I said:
Random users, with seemingly nothing in common experience these issues, and the ‘fixes’ often make no sense at all.
One last thing. Sometimes in order to investigate these error reports, I will copy the user’s inventory and set it to my own test account (so we both have a identical inventory). Sometimes my account experiences the error, sometimes it doesn’t.
The "inventory" I talk about is a table in our database, where each user has a row, and the inventory is just a comma separeated sequence of our internal codes for each products. The codes are a simple number-letter combination.
Example of a inventory that has caused my account to crash:
F2112S04E6B,F2105S03E05,FL21M03V2,F2106S03E06,F2107S04E01,FL20M03V1,F2109S04E03,F2110S04E04,F2111S04E05,F2202S05E02,F2006S1E00,F2208S06E02,F2209S06E03,
Sometimes, if I remove a random product from it, it stops crashing.
PHP version: PHP 8.0.18
Database: 10.6.7-MariaDB
I’m running on a Bitnami WordPress stack
The question: What is causing this error?
I know it’s a complex environment and many things could be at fault, but looking at the code I provided, is anything there that looks potentially guilty?
If the error that I have described is not clear enough, please bare with me as this is a very unique situation which I have never encountered, and I will do my best to make it clearer for you.
EDIT
Tim Morton raised some relevant topics in the comments, so I’ll reply to them here to improve context for this question.
‘Your first "fix" was to print a javascript command?’
- I printed multiple JS commands (console.log) just to see at what point in the PHP script it crashed. When I ran it I noticed that the simple presence of these console.log commands, for some bizarre reason, fixed the crash itself.
‘Then changed the syntax of your loop? This seems aimless.’
- Yes, and yes it does seem aimless, but believe me it worked. That’s why I’m dumbfounded, since it shouldn’t.
‘Is it printing all of the php-generated content and then failing some javascript?’
- No, there is no Javascript here. The only JS was added later (console.log), as I explained, in order to see at what point the PHP crashed. It usually prints the PHP generated product-card.php (included by the loop) and at a random product, stops printing anything, even outside the loop.
‘or is it failing in one particular part of the php loop?’
- I’m pretty sure its in the PHP loop, but I have not been able to narrow it down.
‘To diagnose, you could use try/catch and error_log() to help narrow it down to what is actually failing.’
- Will do! The issue is, simply adding a try/catch will probably ‘fix it’ since as I stated earlier, random changes to the code seem to ‘fix’ the issue temporarily.
‘Does the same record fail every time (hint, it could be the next record that’s actually failing)’
- So far it seems random. I’ve tried modifying the inventory record to place different products at different orders. This sometimes works, sometimes it doesn’t. So far no pattern emerged.
UPDATE
So far, I’ve noticed two types of crashes. One of them it prints out halfway thru on a product-card.php iteration, then crashes (so it doesn’t even get to the other iterations). On one of these cases, it crashed at only the second iteration.
On this specific case I’ve been able to see the front end code thru Chrome dev tools, and I noticed that it crashed right here, at the product-card.php
<a href="https://some-link.com/something/
As you can see, it crashed right after the echo, as it didn’t even put the finishing quote and ‘>’.
On the other type of crash, it’d crash at a random iteration too, only the last iteration it’d finish rendering whatever card it was on and then crash, instead of crashing halfway thru.
I saw people commenting that I should just update or modify my PHP installation and be done with it, and to be honest I may do that since this is happening in prod, but this question is aimed at why this is happening.
3
Answers
After a very exhaustive wild-goose chase, I've come to the conclusion to the (likely) root cause of the issue:
Too many errors and warnings being logged onto the
apache2/error.log
file.Seriously, it was like hundreds of warning logs per second, the file was several GBs large. I don't know exactly why it caused this behaviour, but turning off the logging for everything but critical errors seemed to solve the issue AFAIK (we didn't do anything else, it's AFAIK because we can't be 100% sure that this completely stopped for all our users).
Maybe it was a problem with the exception handler itself, as previously suggested. Maybe it were just too many exceptions to handle, maybe PHP or Apache were overwhelmed with so many logs. We'll never know.
Thank you for everyone who helped, commented and answered, definetely pointed me into the right direction. I were so desperate that I even bountied this, I think. Hopefully this will help another clueless developer out there.
What does contains
$prdLink
?What does contains
$prdImg
?What does contains
$prdTitle
?Are those variables correct sanitized ?
Does contains chars like
"
,'
,>
or anything that could ruins your dom ?PS. If does, I’m afraid you have bigger problem, a security problem (XSS, etc).
I don’t know if that’s a typo made on this post or you copy pasted it but
<a href="https://some-link.com/something/
notice you are missing a"
(sorry to not comment but not enough karma)