feat(checker): add runtime fatal-error prevention check#1320
feat(checker): add runtime fatal-error prevention check#1320faisalahammad wants to merge 2 commits into
Conversation
- Implement RuntimeFatalErrorPreventionSniff to parse and analyze common runtime fatal patterns. - Register check in Default_Check_Repository and ruleset. - Add comprehensive PHPUnit and sniff unit tests. Fixes WordPress#1273
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
The function-call detection seems aligned with the issue scope, since #1273 explicitly includes “calling plugin/theme integration functions without function_exists guard” as one of the runtime fatal patterns. That said, I think this part may need more caution before being added as a stable/default check. A hardcoded list of third-party functions/classes could produce false positives for plugins that declare dependencies or load integrations in a way this sniff cannot understand. Should this initially be experimental, reported as warnings, or made dependency-aware/configurable? Also, the nearby |
|
Thanks for the caution — agreed a hardcoded third-party list could false-positive on plugins that load integrations the sniff cannot statically see. Applied two changes: 1. All findings are now warnings, not errors. Converted every 2. Lists are now filterable. Two new filter hooks let plugin authors extend or override the defaults: add_filter( 'wp_plugin_check_runtime_fatal_error_integration_functions', function( $defaults ) {
return array_merge( $defaults, array( 'my_plugin_helper' ) );
} );
add_filter( 'wp_plugin_check_runtime_fatal_error_optional_classes', function( $defaults ) {
return array_merge( $defaults, array( 'My_Plugin\\Integration' ) );
} );The filter also short-circuits cleanly: returning an empty array disables all third-party-name-based checks if a plugin author wants that. Kept Happy to refine filter names, expand defaults, or switch to experimental — let me know. |
…able - Convert all addError() to addWarning() in RuntimeFatalErrorPreventionSniff - Add <type>warning</type> override in plugin-check.ruleset.xml - Expose integration_functions and optional_classes as filterable lists: - wp_plugin_check_runtime_fatal_error_integration_functions - wp_plugin_check_runtime_fatal_error_optional_classes - Update sniff unit test + integration test to assert warnings, not errors - Add function_exists() guard around apply_filters() so sniff runs under both PHPCS and Plugin Check runner Addresses davidperezgar review feedback on WordPress#1320: hardcoded third-party lists could false-positive on plugins that load integrations the sniff cannot statically see. Findings now require review, do not block submission, and plugin authors can extend or override the defaults. Refs WordPress#1320
Summary
Adds a new static check
Runtime_Fatal_Error_Prevention_Checkand corresponding PHPCS sniffRuntimeFatalErrorPreventionSniffto analyze plugins for high-risk coding patterns that commonly trigger runtime fatal errors. These include unguarded imports, direct/unguarded class instantiations or function calls of optional components, dynamic callback definitions that might be missing, and incorrect class method hook attachments.Fixes #1273
Changes
phpcs-rulesets/plugin-check.ruleset.xml
Before:
After:
Why: Registers the new custom PHPCS sniff under the core plugin-check ruleset to run as part of the PHPCS static checks. Findings are emitted as warnings (not errors) to avoid blocking plugin submission on patterns that may be legitimate for plugins with custom integration loaders.
includes/Checker/Default_Check_Repository.php
Before:
After:
Why: Registers the new
Runtime_Fatal_Error_Prevention_Checkstatic check class into the default check repository so it gets run automatically during plugin checks.Filter hooks for third-party lists
The sniff exposes two filter hooks so plugin authors can extend or override the default lists of optional integration functions and classes:
Returning an empty array disables all third-party-name-based checks.
Testing
Test 1: Run Sniff Unit Tests
vendor/bin/run-phpcs-tests phpcs-sniffs/PluginCheck/Tests/CodeAnalysis/RuntimeFatalErrorPreventionUnitTest.phpResult: Works as expected (All tests pass)
Test 2: Run Plugin Check PHPUnit Integration Tests
npm run wp-env:start:testsnpm run test-php -- --filter=Runtime_Fatal_Error_Prevention_Check_TestsResult: Works as expected (All tests pass)
Test 3: Manual PHPCS run on fixture
vendor/bin/phpcs --standard=phpcs-rulesets/plugin-check.ruleset.xml --sniffs=PluginCheck.CodeAnalysis.RuntimeFatalErrorPrevention tests/phpunit/testdata/plugins/test-plugin-runtime-fatal-error-prevention-with-errors/load.phpResult: 0 errors, 7 warnings at the expected lines (18, 20, 22, 24, 26, 30, 36).