@@ -377,6 +377,17 @@ public function get_access_token( $authorization_code ) {
377377 // If an error occured, log and return it now.
378378 if ( is_wp_error ( $ result ) ) {
379379 $ this ->log ( 'API: Error: ' . $ result ->get_error_message () );
380+
381+ /**
382+ * Perform any actions when obtaining an access token fails.
383+ *
384+ * @since 2.1.1
385+ *
386+ * @param WP_Error $result Error from API.
387+ * @param string $client_id OAuth Client ID.
388+ */
389+ do_action ( 'convertkit_api_get_access_token_error ' , $ result , $ this ->client_id );
390+
380391 return $ result ;
381392 }
382393
@@ -414,6 +425,17 @@ public function refresh_token() {
414425 // If an error occured, log and return it now.
415426 if ( is_wp_error ( $ result ) ) {
416427 $ this ->log ( 'API: Error: ' . $ result ->get_error_message () );
428+
429+ /**
430+ * Perform any actions when refreshing an expired access token fails.
431+ *
432+ * @since 2.1.1
433+ *
434+ * @param WP_Error $result Error from API.
435+ * @param string $client_id OAuth Client ID.
436+ */
437+ do_action ( 'convertkit_api_refresh_token_error ' , $ result , $ this ->client_id );
438+
417439 return $ result ;
418440 }
419441
@@ -1432,39 +1454,55 @@ public function request( $endpoint, $method = 'get', $params = array(), $retry_i
14321454
14331455 // Return the API error message as a WP_Error if the HTTP response code is a 4xx code.
14341456 if ( $ http_response_code >= 400 ) {
1457+
14351458 // Define the error message.
14361459 $ error = $ this ->get_error_message_string ( $ response );
14371460
14381461 $ this ->log ( 'API: Error: ' . $ error );
14391462
14401463 switch ( $ http_response_code ) {
1441- // If the HTTP response code is 401, and the error matches 'The access token expired', refresh the access token now
1442- // and re-attempt the request.
14431464 case 401 :
1444- if ( $ error !== 'The access token expired ' ) {
1445- break ;
1446- }
1447-
1448- // Don't automatically refresh the expired access token if we're not on a production environment.
1449- // This prevents the same ConvertKit account used on both a staging and production site from
1450- // reaching a race condition where the staging site refreshes the token first, resulting in
1451- // the production site unable to later refresh its same expired access token.
1452- if ( ! $ this ->is_production_site () ) {
1453- break ;
1454- }
1455-
1456- // Refresh the access token.
1457- $ result = $ this ->refresh_token ();
1458-
1459- // If an error occured, bail.
1460- if ( is_wp_error ( $ result ) ) {
1461- return $ result ;
1465+ switch ( $ error ) {
1466+ case 'The access token expired ' :
1467+ // Attempt to refresh the access token.
1468+ $ result = $ this ->refresh_token ();
1469+
1470+ // If an error occured, bail.
1471+ if ( is_wp_error ( $ result ) ) {
1472+ return $ result ;
1473+ }
1474+
1475+ // Attempt the request again, now we have a new access token.
1476+ return $ this ->request ( $ endpoint , $ method , $ params , false );
1477+
1478+ case 'The access token is invalid ' :
1479+ $ error = new WP_Error (
1480+ 'convertkit_api_error ' ,
1481+ $ error ,
1482+ $ http_response_code
1483+ );
1484+
1485+ /**
1486+ * Perform any actions when an invalid access token was used.
1487+ *
1488+ * @since 2.1.1
1489+ *
1490+ * @param WP_Error $error WP_Error object.
1491+ * @param string $client_id OAuth Client ID.
1492+ */
1493+ do_action ( 'convertkit_api_access_token_invalid ' , $ error , $ this ->client_id );
1494+
1495+ // Return error.
1496+ return $ error ;
1497+
1498+ default :
1499+ return new WP_Error (
1500+ 'convertkit_api_error ' ,
1501+ $ error ,
1502+ $ http_response_code
1503+ );
14621504 }
14631505
1464- // Attempt the request again, now we have a new access token.
1465- return $ this ->request ( $ endpoint , $ method , $ params , false );
1466-
1467- // If a rate limit was hit, maybe try again.
14681506 case 429 :
14691507 // If retry on rate limit hit is disabled, return a WP_Error.
14701508 if ( ! $ retry_if_rate_limit_hit ) {
@@ -1491,27 +1529,6 @@ public function request( $endpoint, $method = 'get', $params = array(), $retry_i
14911529
14921530 }
14931531
1494- /**
1495- * Helper method to determine the WordPress environment type, checking
1496- * if the wp_get_environment_type() function exists in WordPress (versions
1497- * older than WordPress 5.5 won't have this function).
1498- *
1499- * @since 2.0.2
1500- *
1501- * @return bool
1502- */
1503- private function is_production_site () {
1504-
1505- // If the WordPress wp_get_environment_type() function isn't available,
1506- // assume this is a production site.
1507- if ( ! function_exists ( 'wp_get_environment_type ' ) ) {
1508- return true ;
1509- }
1510-
1511- return ( wp_get_environment_type () === 'production ' );
1512-
1513- }
1514-
15151532 /**
15161533 * Inspects the given API response for errors, returning them as a string.
15171534 *
0 commit comments