Automattic / woocommerce-subscriptions-core

Subscriptions core package for WooCommerce
Other
80 stars 29 forks source link

Catch exceptions thrown and caught by WC during subscription-related scheduled actions #552

Closed james-allan closed 5 months ago

james-allan commented 6 months ago

Fixes #494

Description

There are circumstances that can lead to errors like this one when processing renewals.

Argument 1 passed to WCS_Related_Order_Store_Cached_CPT::add_relation() must be an instance of WC_Order, bool given, called in /public_html/wp-content/plugins/woocommerce-subscriptions/vendor/woocommerce/subscriptions-core/includes/wcs-renewal-functions.php on line 36

The cause is unknown. All we know is that for this error to occur wcs_create_order_from_subscription() must have failed to load the newly created order with wc_get_order() which must have returned false. [code link]

One known reason wc_get_order() will return false is an exception was thrown in WC_Order_Factory::get_order() while the order was being read. What exception? Well we currently don't know because WC catches it, logs it via wc_caught_exception.

This PR improves this by hooking onto woocommerce_caught_exception when we're processing subscription related events. If an exception was caught by WC, we'll now log it on the scheduled action and in the failed scheduled action logs.

Scheduled action log WC log
Screenshot 2023-12-21 at 3 07 40 pm Screenshot 2023-12-21 at 3 10 34 pm

Making that change alone wouldn't solve the WCS_Related_Order_Store_Cached_CPT::add_relation error I mentioned earlier.

To fix that, I've changed wcs_create_order_from_subscription() so that if it fails to load the order, it will throw an exception, roll back the database, return a WP_Error. If you follow that up the chain, that will then lead process_renewal() to try another attempt to create the order. If that fails too, then it will throw an final error.

How to test this PR

  1. Turn on WP post tables if you're using HPOS.
  2. Add the following code to your site to trigger the invalid order exception.
  3. Purchase a subscription.
  4. Go to the Tools > Scheduled actions and run the subscription payment action for that subscripotion.
  5. On trunk you'll notice the scheduled action fails with the WCS_Related_Order_Store_Cached_CPT::add_relation() error.
  6. On this branch the scheduled action will still fail, however the scheduled action will now have the exceptions that were caught and it will also log the full exception stacktrace in the failed-scheduled-actions logs.

Product impact

james-allan commented 5 months ago

Do we want a changelog entry for this one? Maybe something like: ...

Sounds good. I've pushed in https://github.com/Automattic/woocommerce-subscriptions-core/pull/552/commits/9cc7f19554ad158075c37a10273ff47cda43f284