Hooks and Filters
Fatal Error Notify provides several hooks and filters that allow you to customize error handling behavior, modify notification contents, and integrate with your own plugins or themes.
Error Handling Filters
fen_ignore_error
Allows you to completely ignore specific errors before they are processed.
/**
* Filter whether to ignore an error.
*
* @param bool $ignore Whether to ignore the error.
* @param array $error The error data array.
*/
add_filter( 'fen_ignore_error', function( $ignore, $error ) {
// Ignore all warnings from a specific plugin
if ( isset( $error['file'] ) && strpos( $error['file'], 'problematic-plugin' ) !== false ) {
return true;
}
return $ignore;
}, 10, 2 );
fen_is_error_type_enabled
Filter whether an error type is enabled for notifications on a specific channel.
/**
* Filter whether an error type is enabled for notifications.
*
* @param bool $enabled Whether the error type is enabled.
* @param array $error The error data array containing 'type' and other details.
* @param string $channel The notification channel (email, slack, twilio, echodash) or false for any channel.
*/
add_filter( 'fen_is_error_type_enabled', function( $enabled, $error, $channel ) {
// Only send critical WooCommerce errors to Slack
if ( $channel === 'slack' && strpos( $error['type'], 'woocommerce_' ) === 0 ) {
return in_array( $error['type'], [ 'woocommerce_emergency', 'woocommerce_critical' ] );
}
return $enabled;
}, 10, 3 );
fen_is_error_paused
Filter whether an error notification is paused.
/**
* Filter whether an error notification is paused.
*
* @param bool $paused Whether the error notification is paused.
* @param array $error The error data array.
*/
add_filter( 'fen_is_error_paused', function( $paused, $error ) {
// Pause all errors during maintenance mode
if ( wp_maintenance_mode() ) {
return true;
}
return $paused;
}, 10, 2 );
fen_is_rate_limited
Filter whether an error notification is rate limited.
/**
* Filter whether an error notification is rate limited.
*
* @param bool $rate_limited Whether the error is currently rate limited.
* @param array $error The error data array.
*/
add_filter( 'fen_is_rate_limited', function( $rate_limited, $error ) {
// Never rate limit critical errors
if ( isset( $error['type'] ) && $error['type'] === E_ERROR ) {
return false;
}
return $rate_limited;
}, 10, 2 );
Rate Limiting Customization
fen_rate_limit_time
Customize the rate limiting time period (default is 1 hour).
/**
* Change rate limiting to 30 minutes instead of 1 hour.
*/
add_filter( 'fen_rate_limit_time', function( $time ) {
return 30 * MINUTE_IN_SECONDS;
} );
fen_rate_limit_data
Customize what data is used to generate the rate limiting hash.
/**
* Include user ID in rate limiting to separate errors by user.
*
* @param array $rate_limit_data The data to use for rate limiting.
* @param array $error The full error data array.
*/
add_filter( 'fen_rate_limit_data', function( $rate_limit_data, $error ) {
if ( isset( $error['user'] ) ) {
$rate_limit_data['user'] = $error['user'];
}
return $rate_limit_data;
}, 10, 2 );
Notification Content Filters
fen_error
Filter the error data before sending notifications.
/**
* Filter the error data before sending notifications.
*
* @param array $error The error data array.
*/
add_filter( 'fen_error', function( $error ) {
// Add custom context to error messages
if ( isset( $error['message'] ) ) {
$error['message'] = '[Site: ' . get_bloginfo( 'name' ) . '] ' . $error['message'];
}
return $error;
} );
fen_email_notification_output
Filter the email notification output.
/**
* Filter the email notification output.
*
* @param string $output The email notification output.
* @param array $error The error data array.
*/
add_filter( 'fen_email_notification_output', function( $output, $error ) {
// Add custom footer to email notifications
$output .= '
Need help? Contact support at [email protected]
';
return $output;
}, 10, 2 );
fen_email_notification_subject
Filter the email notification subject.
/**
* Filter the email notification subject.
*
* @param string $subject The email notification subject.
* @param array $error The error data array.
*/
add_filter( 'fen_email_notification_subject', function( $subject, $error ) {
// Add priority indicator for fatal errors
if ( isset( $error['type'] ) && $error['type'] === E_ERROR ) {
$subject = '[URGENT] ' . $subject;
}
return $subject;
}, 10, 2 );
fen_full_request_url
Filter the full request URL included in notifications.
/**
* Filter the full request URL.
*
* @param string $url The full request URL.
* @param array $error The error data array.
*/
add_filter( 'fen_full_request_url', function( $url, $error ) {
// Add UTM parameters for tracking
return add_query_arg( 'utm_source', 'error_notification', $url );
}, 10, 2 );
WordPress Mail Integration
fen_use_wp_mail
Control whether to use WordPress’s wp_mail() function or PHP’s mail() function.
/**
* Force use of PHP mail() instead of wp_mail().
*/
add_filter( 'fen_use_wp_mail', '__return_false' );
Action Hooks
Error Processing Actions
fen_handle_error
Fired when an error is being handled, before notifications are sent.
/**
* Log all errors to a custom log file.
*
* @param array $error The error data array.
*/
add_action( 'fen_handle_error', function( $error ) {
error_log(
'[' . date( 'Y-m-d H:i:s' ) . '] FEN Error: ' . print_r( $error, true ),
3,
WP_CONTENT_DIR . '/custom-error.log'
);
} );
fen_handle_error_{type}
Fired for specific error types (e.g., fen_handle_error_1 for E_ERROR).
/**
* Send critical errors to external monitoring service.
*/
add_action( 'fen_handle_error_1', function( $error ) { // E_ERROR = 1
// Send to external monitoring service
wp_remote_post( 'https://monitoring.example.com/api/errors', [
'body' => json_encode( $error ),
'headers' => [ 'Content-Type' => 'application/json' ]
] );
} );
Settings Management
Getting Settings
Access Fatal Error Notify settings programmatically:
// Get all settings
$settings = fatal_error_notify()->admin->get_all();
// Get a specific setting
$email = fatal_error_notify()->admin->get( 'notification_email' );
// Get setting with default value
$slack_channel = fatal_error_notify()->admin->get( 'slack_channel_id', '#general' );
Setting Filters
fen_get_setting_{key}
Filter individual setting values when they’re retrieved.
/**
* Override license key from wp-config.php constant.
*/
add_filter( 'fen_get_setting_license_key', function( $license_key ) {
if ( defined( 'FATAL_ERROR_NOTIFY_LICENSE_KEY' ) ) {
return FATAL_ERROR_NOTIFY_LICENSE_KEY;
}
return $license_key;
} );
Creating Custom Integrations
Fatal Error Notify supports custom plugin integrations through an extensible architecture. You can create integrations for your own plugins or third-party plugins.
Integration Class Structure
Create a class that extends FEN_Integration:
class FEN_My_Plugin extends FEN_Integration {
public $slug = 'my-plugin';
public $title = 'My Plugin';
/**
* Initialize hooks specific to this integration.
*/
public function init() {
add_action( 'my_plugin_error', array( $this, 'handle_plugin_error' ) );
add_filter( 'my_plugin_setting', array( $this, 'enable_error_logging' ) );
}
/**
* Get registered error types for this integration.
*
* @return array Types
*/
public function get_error_types() {
return array(
'api_error' => __( 'API Connection Error', 'my-plugin' ),
'validation' => __( 'Data Validation Error', 'my-plugin' ),
'payment_failed' => __( 'Payment Processing Error', 'my-plugin' ),
);
}
/**
* Handle errors from our plugin.
*/
public function handle_plugin_error( $error_data ) {
$error = array(
'type' => $error_data['type'], // Should match a key from get_error_types()
'message' => $error_data['message'],
'user' => get_current_user_id(),
);
// Add additional context if available
if ( isset( $error_data['context'] ) ) {
$error['message'] .= "\n\nContext: " . print_r( $error_data['context'], true );
}
$this->handle_error( $error );
}
/**
* Enable error logging in our plugin.
*/
public function enable_error_logging( $value ) {
// Force enable logging if FEN integration is active
if ( $this->is_enabled() ) {
return true;
}
return $value;
}
}
// Initialize the integration
new FEN_My_Plugin();
Integration Registration
Register your integration with Fatal Error Notify using the fen_integrations filter:
/**
* Register custom integrations.
*
* @param array $integrations Existing integrations.
* @return array Modified integrations.
*/
add_filter( 'fen_integrations', function( $integrations ) {
$integrations['my-plugin'] = 'My_Plugin_Main_Class';
return $integrations;
} );
Integration Helper Methods
The FEN_Integration base class provides several helper methods:
// Check if integration is enabled for any notification channel
if ( $this->is_enabled() ) {
// Integration is active
}
// Get enabled notification channels
$channels = $this->get_enabled_channels(); // Returns array like ['email', 'slack']
// Get enabled error types
$types = $this->get_enabled_types(); // Returns array like ['api_error' => true]
Manual Error Triggering
You can manually trigger error notifications from your code:
Trigger PHP Error Notification
$error = array(
'type' => E_WARNING,
'message' => 'Custom error message from my plugin',
'file' => __FILE__,
'line' => __LINE__,
'user' => get_current_user_id(),
);
fatal_error_notify()->public->handle_error( $error );
Trigger Custom Integration Error
// Assuming you have a custom integration class instance
$integration = fatal_error_notify()->integrations->{'my-plugin'};
$error = array(
'type' => 'api_error', // Must match a type from get_error_types()
'message' => 'API connection failed: timeout after 30 seconds',
'user' => get_current_user_id(),
);
$integration->handle_error( $error );
WP-CLI Commands
Fatal Error Notify includes WP-CLI support for managing settings programmatically.
Available Commands
Get All Options
wp fatal-error-notify get_options
Get Specific Option
wp fatal-error-notify get_option notification_email
wp fatal-error-notify get_option levels
Update Option
# Simple value
wp fatal-error-notify update_option notification_email [email protected]
# Array value (JSON format)
wp fatal-error-notify update_option levels '{"1":true,"2":false,"4":true}'
Bulk Updates
# Update email on all sites in multisite
wp site list --field=url | xargs -n1 -I {} sh -c 'wp --url={} fatal-error-notify update_option notification_email [email protected]'
Error Data Structure
Understanding the error data structure helps when working with hooks and filters.
PHP Error Structure
array(
'type' => 1, // PHP error constant (E_ERROR, E_WARNING, etc.)
'message' => 'Error message',
'file' => 'path/to/file.php',
'line' => 123,
'user' => 1, // WordPress user ID (if available)
)
Plugin Integration Error Structure
array(
'type' => 'plugin_error_type', // Integration slug + underscore + error type
'message' => 'Error message',
'user' => 1, // WordPress user ID (if available)
'url' => 'https://...', // Optional: relevant URL
'file' => 'path/to/file.php', // Optional: relevant file
'line' => 123, // Optional: relevant line number
)
HTTP Error Structure
array(
'type' => 'http_error',
'message' => 'HTTP API error: timeout',
'url' => 'https://api.example.com/endpoint',
'user' => 1,
)
JavaScript Error Structure
array(
'type' => 'js_fatal',
'message' => 'Uncaught TypeError: Cannot read property...',
'url' => 'https://yoursite.com/page',
'file' => 'script.js',
'line' => 42,
'user' => 1,
)
Best Practices
Performance Considerations
- Rate Limiting: Always respect rate limiting to avoid notification spam
- Conditional Loading: Only load integration code when the target plugin is active
- Non-blocking: Use non-blocking HTTP requests for external notifications
- Memory Management: Be mindful of memory usage in error handlers
Security
- Sanitize Data: Always sanitize error data before processing
- Capability Checks: Verify user capabilities before allowing configuration changes
- Nonce Verification: Use nonces for AJAX requests and form submissions
- Data Validation: Validate all input data, especially from external sources
Error Handling
- Graceful Degradation: Ensure your code doesn’t break if Fatal Error Notify is deactivated
- Avoid Recursion: Be careful not to trigger errors within error handlers
- Logging: Use WordPress’s built-in logging functions when possible
- Testing: Test error scenarios thoroughly, including edge cases
Troubleshooting
Common Issues
Integration Not Appearing in Settings
- Ensure the target plugin class exists and is loaded
- Check that your integration is registered with the
fen_integrationsfilter - Verify the integration file is being included properly
Notifications Not Sending
- Check if the error type is enabled in the plugin settings
- Verify rate limiting isn’t preventing notifications
- Ensure the error isn’t being filtered out by custom hooks
- Check notification channel settings (email, Slack, etc.)
Custom Error Types Not Working
- Ensure error types are returned by
get_error_types() - Check that the error type matches exactly (case-sensitive)
- Verify the integration prefix is being added correctly
Debugging
Enable WordPress debug logging to troubleshoot issues:
// Add to wp-config.php
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
// Add debug logging to your integration
error_log( 'FEN Debug: ' . print_r( $error_data, true ) );
Examples
Custom Error Logger
/**
* Log all Fatal Error Notify errors to a custom table.
*/
add_action( 'fen_handle_error', function( $error ) {
global $wpdb;
$wpdb->insert(
$wpdb->prefix . 'custom_error_log',
array(
'error_type' => $error['type'],
'message' => $error['message'],
'file' => isset( $error['file'] ) ? $error['file'] : '',
'line' => isset( $error['line'] ) ? $error['line'] : 0,
'user_id' => isset( $error['user'] ) ? $error['user'] : 0,
'url' => isset( $error['url'] ) ? $error['url'] : '',
'timestamp' => current_time( 'mysql' ),
),
array( '%s', '%s', '%s', '%d', '%d', '%s', '%s' )
);
} );
Conditional Notifications
/**
* Only send notifications during business hours.
*/
add_filter( 'fen_ignore_error', function( $ignore, $error ) {
$current_hour = (int) current_time( 'H' );
// Business hours: 9 AM to 5 PM
if ( $current_hour < 9 || $current_hour >= 17 ) {
// Still log critical errors, but don't send notifications
if ( isset( $error['type'] ) && $error['type'] !== E_ERROR ) {
return true;
}
}
return $ignore;
}, 10, 2 );
Enhanced Error Context
/**
* Add additional context to all error notifications.
*/
add_filter( 'fen_error', function( $error ) {
// Add server information
$error['message'] .= "\n\n--- Server Info ---\n";
$error['message'] .= "PHP Version: " . PHP_VERSION . "\n";
$error['message'] .= "WordPress Version: " . get_bloginfo( 'version' ) . "\n";
$error['message'] .= "Memory Usage: " . size_format( memory_get_usage( true ) ) . "\n";
$error['message'] .= "Peak Memory: " . size_format( memory_get_peak_usage( true ) ) . "\n";
// Add active plugins
if ( function_exists( 'get_plugins' ) ) {
$active_plugins = get_option( 'active_plugins', array() );
$error['message'] .= "Active Plugins: " . count( $active_plugins ) . "\n";
}
return $error;
} );