diff --git a/includes/run.php b/includes/run.php
index 03b90a43b97d51362360bf32d8ad20117ed901a8..b12a983d15b20c419f6dc29c065ddf9fcc414872 100644
--- a/includes/run.php
+++ b/includes/run.php
@@ -7,6 +7,7 @@
 
 namespace Automattic\WP\WP_CLI_Cron_Control_Offload;
 use WP_CLI;
+use WP_Error;
 
 /**
  * Intended for non-interactive use, so all output ends up in the error log
@@ -16,14 +17,14 @@ use WP_CLI;
  */
 function run_event( $command ) {
 	if ( ! defined( 'WP_CLI' ) || ! \WP_CLI ) {
-		/* translators: 1: Plugin's prefix for log messages, 2. WP-CLI command that would have run */
-		trigger_error( sprintf( __( '%1$s: Attempted to run event without WP-CLI loaded. (%2$s)', 'wp-cli-cron-control-offload' ), MESSAGE_PREFIX, var_export( $command, true ) ), E_USER_WARNING );
+		$no_wp_cli = new WP_Error( 'no-wp-cli', __( 'Attempted to run event without WP-CLI loaded.', 'wp-cli-cron-control-offload' ) );
+		do_action( 'wp_cli_cron_control_offload_run_error', $no_wp_cli, $command );
 		return;
 	}
 
-	if ( ! validate_command( $command ) ) {
-		/* translators: 1: Plugin's prefix for log messages, 2. WP-CLI command that would have run */
-		trigger_error( sprintf( __( '%1$s: Attempted to run blocked command. (%2$s)', 'wp-cli-cron-control-offload' ), MESSAGE_PREFIX, var_export( $command, true ) ), E_USER_WARNING );
+	$validated = validate_command( $command );
+	if ( is_wp_error( $validated ) ) {
+		do_action( 'wp_cli_cron_control_offload_run_error', $validated, $command );
 		return;
 	}
 
@@ -38,12 +39,12 @@ function run_event( $command ) {
 	$end = microtime( true );
 
 	// Command failed.
-	if ( ! is_object( $output ) || is_wp_error( $output ) ) {
-		/* translators: 1: Plugin's prefix for log messages, 2. Command error that caused failure */
-		trigger_error( sprintf( __( '%1$s: Command failed. (%2$s)', 'wp-cli-cron-control-offload' ), MESSAGE_PREFIX, var_export( $command, true ) ), E_USER_WARNING );
-
-		$message = is_wp_error( $output ) ? $output->get_error_message() : var_export( $output, true );
-		trigger_error( $message, E_USER_WARNING );
+	if ( is_wp_error( $output ) ) {
+		do_action( 'wp_cli_cron_control_offload_run_error', $output, $command );
+		return;
+	} elseif ( ! is_object( $output ) ) {
+		$error = new WP_Error( 'command-run-unknown-failure', __( 'Command execution failed with an unexpected error.', 'wp-cli-cron-control-offload' ), $output );
+		do_action( 'wp_cli_cron_control_offload_run_error', $error, $command );
 		return;
 	}
 
@@ -53,9 +54,6 @@ function run_event( $command ) {
 	$output->end      = $end;
 	$output->duration = $end - $start;
 
-	$output = var_export( $output, true );
-	$output = MESSAGE_PREFIX . ":\n{$output}";
-
-	error_log( $output );
+	do_action( 'wp_cli_cron_control_offload_run_success', $output, $command );
 }
 add_action( ACTION, __NAMESPACE__ . '\run_event' );
diff --git a/languages/wp-cli-cron-control-offload.pot b/languages/wp-cli-cron-control-offload.pot
index 9a4bdff21997b243c9b7cd460ebaa1fd71a52226..2d42d5f1d57c5cd5942a73706d92095e03ce4d4c 100644
--- a/languages/wp-cli-cron-control-offload.pot
+++ b/languages/wp-cli-cron-control-offload.pot
@@ -5,7 +5,7 @@ msgstr ""
 "Project-Id-Version: WP-CLI Cron Control Offload 0.1.0\n"
 "Report-Msgid-Bugs-To: "
 "https://wordpress.org/support/plugin/wp-cli-cron-control-offload\n"
-"POT-Creation-Date: 2017-09-12 22:53:17+00:00\n"
+"POT-Creation-Date: 2017-09-14 02:19:58+00:00\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -58,21 +58,11 @@ msgid "Failed to convert command array to string."
 msgstr ""
 
 #: includes/run.php:20
-#. translators: 1: Plugin's prefix for log messages, 2. WP-CLI command that
-#. would have run
-msgid "%1$s: Attempted to run event without WP-CLI loaded. (%2$s)"
+msgid "Attempted to run event without WP-CLI loaded."
 msgstr ""
 
-#: includes/run.php:26
-#. translators: 1: Plugin's prefix for log messages, 2. WP-CLI command that
-#. would have run
-msgid "%1$s: Attempted to run blocked command. (%2$s)"
-msgstr ""
-
-#: includes/run.php:43
-#. translators: 1: Plugin's prefix for log messages, 2. Command error that
-#. caused failure
-msgid "%1$s: Command failed. (%2$s)"
+#: includes/run.php:46
+msgid "Command execution failed with an unexpected error."
 msgstr ""
 
 #. Plugin Name of the plugin/theme