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
HPOS: fix handling order meta containing nonexistent class when sync is on #43517
HPOS: fix handling order meta containing nonexistent class when sync is on #43517
Conversation
Test Results SummaryCommit SHA: b9b4a4e
To view the full API test report, click here. To view the full E2E test report, click here. To view all test reports, visit the WooCommerce Test Reports Dashboard. |
Hi @jorgeatorres, @Konamiman, @vedanshujain, Apart from reviewing the code changes, please make sure to review the testing instructions as well. You can follow this guide to find out what good testing instructions should look like: |
I get an error when trying to run all the tests of the file (so without the
|
@Konamiman Unfortunately I cannot reproduce this locally. Checking out this branch, running
Did you run Note that all the CI checks pass and the class that is not being found in your setup doesn't seem to have anything to do with the changes in this PR -- seems like this could be a local issue? |
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.
Looks good to me, but we need to modify testing instructions so that folks are able to test it without unit test setup. Perhaps we can use a small dummy plugin that adds a class and we can then enable/disable that plugin during testing.
@lsinger I'm running the test as follows: |
Good point @vedanshujain. I've add testing instructions for situations where git and unit tests might not be available. Please take another look. |
@Konamiman Should -- maybe. Maybe adding the configuration file argument explicitly makes a difference? |
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.
Looks good, can you add one more test which checks for deleting meta as well, just like we are covering adding meta.
plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php
Outdated
Show resolved
Hide resolved
plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php
Outdated
Show resolved
Hide resolved
@lsinger What fixes the test for me is adding the following to the test: require_once __DIR__ . '/../../../../../legacy/unit-tests/webhooks/functions.php'; I think this makes sense, as we are referencing a file in |
@lsinger: While looking at this it occurred to me that instead of trying to capture the throwable and determine its nature by the error message, we could preemptively detect when I know it's not exactly the same logic but given we only seem to care about that one throwable, the result is pretty much the same (and maybe even bit cleaner). There might be some limitation I'm ignoring, so please let me know if that's the case 😸. |
@Konamiman interesting -- this should be a problem on |
Thank you @jorgeatorres, that's a great suggestion -- I implemented it in 1abb8ed. There might of course be other cases where an exception is thrown, but we haven't come across them yet -- and the old solution would have rethrown them anyway. So I agree that we should prefer this simpler way of handling things. |
Addresses all review comments, would love to get another review. |
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.
@lsinger: Thanks for making the changes. I haven't properly tested this yet, but I noticed a few things in the code, and so I'm leaving some feedback. Luckily, nothing serious. Let me know what you think.
plugins/woocommerce/includes/data-stores/abstract-wc-order-data-store-cpt.php
Outdated
Show resolved
Hide resolved
plugins/woocommerce/includes/data-stores/abstract-wc-order-data-store-cpt.php
Outdated
Show resolved
Hide resolved
plugins/woocommerce/includes/data-stores/abstract-wc-order-data-store-cpt.php
Outdated
Show resolved
Hide resolved
plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php
Outdated
Show resolved
Hide resolved
Thank you for having my back, @jorgeatorres -- I should have caught these. All great notes / suggestions, I made the changes. ✅ |
@jorgeatorres @lsinger , re: the It's still should be fine, unless you can think of a scenario when it isn't. |
I can't think of a scenario where it wouldn't be fine to go the alternative route. Note also that we do log the instances where we go that way, so it wouldn't be able to happen completely invisibly. |
Hey @vedanshujain!
I agree, that's why I said that it was mostly but not exactly "the same".
We could mitigate this bit by adding a PHP version check, but not sure if it's worth it. As for
I can't think of one right now but "never say never". Considering this is already an edge case, I'd expect this new code not be hit very often so we would at least have some room to improve it if necessary.
@lsinger: Could you expand on this? I don't think we're logging anything now that we would handle the exception before it even occurs. Maybe actually logging this unusual instance of meta sync wouldn't be a bad idea. |
🤦 No, we're not -- I was thinking of #43739. So let me rephrase: we should log this. 💯 I'll add that. |
Ok sounds good, let's ship then! |
@jorgeatorres @vedanshujain added logging in 0beb5d5.
FWIW, someone needs to actually hit the "approve" button. 😅 |
I rather think that when running the full test suite (or with |
@Konamiman my intuition is that we should create an individual PR for this as it's fixing a different issue. What do you think? |
Submission Review Guidelines:
Changes proposed in this Pull Request:
Assume a plugin adds metadata to an order, and that metadata is a serialized object that uses a class that the plugin defines. Now assume the plugin is subsequently deactivated and the class definition necessary for deserializing the object in the order's metadata isn't available anymore.
This is not an issue as long as the metadata isn't touched, but with HPOS and sync turned on, there are situations where the metadata is deserialized, changed (by WordPress Core’s
map_deep
), and the serialized again. Under PHP less than 8 this was not an issue, but under PHP 8 throws an error.There is an open ticket in WordPress Core for this issue but it’s not clear when, how, and if the issue will be addressed. So to ship a fix for WooCommerce users experiencing this issue, this PR catches the error and tries to imitate the metadata actions using
$wpdb
directly.Detecting this specific error can, as far as I can tell, only be done by matching the kind of error message, which I find a bit sub-optimal. I'd love to hear ideas for alternative ways of detection.
Closes #38304.
How to test the changes in this Pull Request:
Using the WooCommerce Testing Instructions Guide, include your detailed testing instructions:
nvm use && wp-env stop && WP_ENV_PHP_VERSION=8.0 wp-env start && pnpm test:php:env --filter=test_unserialize_meta_with_nonexistent_class
-- the test should passgit checkout 19b2ddf
pnpm test:php:env --filter=test_unserialize_meta_with_nonexistent_class
-- the test should now failInstructions for Manual Testing
__ID__
with the ID of the order you just created. Make sure to select the "execute only once" option.http://localhost:8888/wp-admin/admin.php?page=wc-status&tab=logs
), the error should be in there as well.Changelog entry
Significance
Type
Message
Comment