From 45c66e6253f7b23d1ae7213efd01e4fcfccd6766 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Mon, 6 Apr 2020 21:56:41 -0700 Subject: [PATCH 1/3] Expose fatal errors that occur while validating a URL --- includes/class-amp-theme-support.php | 14 ++++-- .../cli/class-amp-cli-validation-command.php | 2 +- .../options/class-amp-options-manager.php | 2 +- .../class-amp-validated-url-post-type.php | 47 +++++++++++++++++-- .../class-amp-validation-manager.php | 9 +++- 5 files changed, 64 insertions(+), 10 deletions(-) diff --git a/includes/class-amp-theme-support.php b/includes/class-amp-theme-support.php index 47170285c1b..bb15811639a 100644 --- a/includes/class-amp-theme-support.php +++ b/includes/class-amp-theme-support.php @@ -2025,10 +2025,16 @@ public static function prepare_response( $response, $args = [] ) { if ( AMP_Validation_Manager::$is_validate_request ) { status_header( 200 ); header( 'Content-Type: application/json; charset=utf-8' ); - return wp_json_encode( - AMP_Validation_Manager::get_validate_response_data( $sanitization_results ), - JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES - ); + $data = [ + 'http_status_code' => $status_code, + 'php_fatal_error' => false, + ]; + $last_error = error_get_last(); + if ( $last_error && in_array( $last_error['type'], [ E_ERROR, E_RECOVERABLE_ERROR, E_CORE_ERROR, E_COMPILE_ERROR ], true ) ) { + $data['php_fatal_error'] = $last_error; + } + $data = array_merge( $data, AMP_Validation_Manager::get_validate_response_data( $sanitization_results ) ); + return wp_json_encode( $data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ); } // Determine what the validation errors are. diff --git a/includes/cli/class-amp-cli-validation-command.php b/includes/cli/class-amp-cli-validation-command.php index ba8a708d274..1857ac38795 100644 --- a/includes/cli/class-amp-cli-validation-command.php +++ b/includes/cli/class-amp-cli-validation-command.php @@ -701,7 +701,7 @@ private function validate_and_store_url( $url, $type ) { AMP_Validated_URL_Post_Type::store_validation_errors( $validation_errors, $validity['url'], - wp_array_slice_assoc( $validity, [ 'queried_object', 'stylesheets' ] ) + wp_array_slice_assoc( $validity, [ 'queried_object', 'stylesheets', 'php_fatal_error' ] ) ); $unaccepted_error_count = count( array_filter( diff --git a/includes/options/class-amp-options-manager.php b/includes/options/class-amp-options-manager.php index a654f0b1e8c..889b1a05717 100644 --- a/includes/options/class-amp-options-manager.php +++ b/includes/options/class-amp-options-manager.php @@ -580,7 +580,7 @@ public static function handle_updated_theme_support_option() { $invalid_url_post_id = AMP_Validated_URL_Post_Type::store_validation_errors( $errors, $url, - wp_array_slice_assoc( $validation, [ 'queried_object', 'stylesheets' ] ) + wp_array_slice_assoc( $validation, [ 'queried_object', 'stylesheets', 'php_fatal_error' ] ) ); $invalid_url_screen_url = ! is_wp_error( $invalid_url_post_id ) ? get_edit_post_link( $invalid_url_post_id, 'raw' ) : null; diff --git a/includes/validation/class-amp-validated-url-post-type.php b/includes/validation/class-amp-validated-url-post-type.php index 2b24d051a1a..39caf9a8412 100644 --- a/includes/validation/class-amp-validated-url-post-type.php +++ b/includes/validation/class-amp-validated-url-post-type.php @@ -848,6 +848,14 @@ public static function store_validation_errors( $validation_errors, $url, $args // Note that json_encode() is being used here because wp_slash() will coerce scalar values to strings. update_post_meta( $post_id, '_amp_stylesheets', wp_slash( wp_json_encode( $args['stylesheets'] ) ) ); } + if ( isset( $args['php_fatal_error'] ) ) { + if ( empty( $args['php_fatal_error'] ) ) { + delete_post_meta( $post_id, '_amp_php_fatal_error' ); + } else { + // Note that json_encode() is being used here because wp_slash() will coerce scalar values to strings. + update_post_meta( $post_id, '_amp_php_fatal_error', wp_slash( wp_json_encode( $args['php_fatal_error'] ) ) ); + } + } delete_transient( static::NEW_VALIDATION_ERROR_URLS_COUNT_TRANSIENT ); @@ -1291,7 +1299,7 @@ public static function handle_bulk_action( $redirect, $action, $items ) { self::store_validation_errors( $validation_errors, $validity['url'], - wp_array_slice_assoc( $validity, [ 'queried_object', 'stylesheets' ] ) + wp_array_slice_assoc( $validity, [ 'queried_object', 'stylesheets', 'php_fatal_error' ] ) ); $unaccepted_error_count = count( array_filter( @@ -1401,6 +1409,11 @@ public static function print_admin_notice() { ); } + // Add notice for PHP fatal error during validation request. + if ( 'post' === get_current_screen()->base && self::POST_TYPE_SLUG === get_current_screen()->post_type && get_post() ) { + self::render_php_fatal_error_admin_notice( get_post() ); + } + /** * Adds notices to the single error page. * 1. Notice with detailed error information in an expanding box. @@ -1502,6 +1515,34 @@ public static function print_admin_notice() { } } + /** + * Render PHP fatal error admin notice. + * + * @param WP_Post $post Post. + */ + private static function render_php_fatal_error_admin_notice( WP_Post $post ) { + $error = get_post_meta( $post->ID, '_amp_php_fatal_error', true ); + if ( empty( $error ) ) { + return; + } + $error_data = json_decode( $error, true ); + if ( ! is_array( $error_data ) || ! isset( $error_data['message'], $error_data['file'], $error_data['line'] ) ) { + return; + } + ?> +
+

+
+
+
+

+ + +

+
+ $post, ], - wp_array_slice_assoc( $validity, [ 'queried_object', 'stylesheets' ] ) + wp_array_slice_assoc( $validity, [ 'queried_object', 'stylesheets', 'php_fatal_error' ] ) ) ); if ( is_wp_error( $stored ) ) { @@ -1633,7 +1674,7 @@ public static function recheck_post( $post ) { [ 'invalid_url_post' => $post, ], - wp_array_slice_assoc( $validity, [ 'queried_object', 'stylesheets' ] ) + wp_array_slice_assoc( $validity, [ 'queried_object', 'stylesheets', 'php_fatal_error' ] ) ) ); foreach ( $validation_errors as $error ) { diff --git a/includes/validation/class-amp-validation-manager.php b/includes/validation/class-amp-validation-manager.php index ce1323589a8..09d1a846fef 100644 --- a/includes/validation/class-amp-validation-manager.php +++ b/includes/validation/class-amp-validation-manager.php @@ -726,7 +726,7 @@ function( $post ) { [ 'invalid_url_post' => $invalid_url_post_id, ], - wp_array_slice_assoc( $validity, [ 'queried_object', 'stylesheets' ] ) + wp_array_slice_assoc( $validity, [ 'queried_object', 'stylesheets', 'php_fatal_error' ] ) ) ); @@ -2242,6 +2242,13 @@ public static function get_validate_url_error_message( $error_code, $error_messa $support_forum_message, ] ); + case 'fatal_error_during_validation': + return $implode_non_empty_strings_with_spaces_and_sanitize( + [ + esc_html__( 'A PHP fatal error occurred while validating the URL. This may indicate either a bug in theme/plugin code or it may be due to an issue in the AMP plugin itself. The error details appear below.', 'amp' ), + $support_forum_message, + ] + ); case 'response_not_json': return $implode_non_empty_strings_with_spaces_and_sanitize( [ From 71e15246e9a72557832508ee7f356d3824ff9e14 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 7 Apr 2020 07:36:22 -0700 Subject: [PATCH 2/3] Account for more types of fatal errors Co-Authored-By: Alain Schlesser --- includes/class-amp-theme-support.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-amp-theme-support.php b/includes/class-amp-theme-support.php index bb15811639a..bd5a8303c7f 100644 --- a/includes/class-amp-theme-support.php +++ b/includes/class-amp-theme-support.php @@ -2030,7 +2030,7 @@ public static function prepare_response( $response, $args = [] ) { 'php_fatal_error' => false, ]; $last_error = error_get_last(); - if ( $last_error && in_array( $last_error['type'], [ E_ERROR, E_RECOVERABLE_ERROR, E_CORE_ERROR, E_COMPILE_ERROR ], true ) ) { + if ( $last_error && in_array( $last_error['type'], [ E_ERROR, E_RECOVERABLE_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_PARSE ], true ) ) { $data['php_fatal_error'] = $last_error; } $data = array_merge( $data, AMP_Validation_Manager::get_validate_response_data( $sanitization_results ) ); From 6da70d75756f4ef73808bcfbd6ddca984dbcccd0 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 7 Apr 2020 07:37:13 -0700 Subject: [PATCH 3/3] Improve retrieval of post object Co-Authored-By: Alain Schlesser --- includes/validation/class-amp-validated-url-post-type.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/includes/validation/class-amp-validated-url-post-type.php b/includes/validation/class-amp-validated-url-post-type.php index 39caf9a8412..a6a4c853ce1 100644 --- a/includes/validation/class-amp-validated-url-post-type.php +++ b/includes/validation/class-amp-validated-url-post-type.php @@ -1410,8 +1410,9 @@ public static function print_admin_notice() { } // Add notice for PHP fatal error during validation request. - if ( 'post' === get_current_screen()->base && self::POST_TYPE_SLUG === get_current_screen()->post_type && get_post() ) { - self::render_php_fatal_error_admin_notice( get_post() ); + $post = get_post(); + if ( $post instanceof WP_Post && 'post' === get_current_screen()->base && self::POST_TYPE_SLUG === get_current_screen()->post_type ) { + self::render_php_fatal_error_admin_notice( $post ); } /**