fix: widen all catch blocks from \Exception to \Throwable

PHP 8.3 TypeError and Error extend \Throwable but NOT \Exception,
so catch(\Exception) silently drops them — explaining why the
generation pipeline fails at the publishing step with no activity
log entry. Now every catch in the generation path catches
\Throwable and logs the exception class name for diagnostics.

Bump to v0.2.7.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
peptiderepo
2026-04-18 10:12:06 +07:00
parent 14e4270158
commit 1968864073
8 changed files with 39 additions and 24 deletions

View File

@@ -34,8 +34,11 @@ class PRAutoBlogger_Executor {
try {
( new PRAutoBlogger_Pipeline_Runner() )->run();
} catch ( \Exception $e ) {
PRAutoBlogger_Logger::instance()->error( 'Daily generation FAILED: ' . $e->getMessage(), 'scheduler' );
} catch ( \Throwable $e ) {
PRAutoBlogger_Logger::instance()->error(
sprintf( 'Daily generation %s: %s', get_class( $e ), $e->getMessage() ),
'scheduler'
);
} finally {
$this->release_generation_lock();
}
@@ -48,8 +51,11 @@ class PRAutoBlogger_Executor {
public function on_collect_metrics(): void {
try {
( new PRAutoBlogger_Metrics_Collector() )->collect_all();
} catch ( \Exception $e ) {
PRAutoBlogger_Logger::instance()->error( 'Metrics collection FAILED: ' . $e->getMessage(), 'metrics' );
} catch ( \Throwable $e ) {
PRAutoBlogger_Logger::instance()->error(
sprintf( 'Metrics collection %s: %s', get_class( $e ), $e->getMessage() ),
'metrics'
);
}
}
@@ -87,8 +93,11 @@ class PRAutoBlogger_Executor {
->set_skip_dedup( true )
->run();
wp_send_json_success( $results );
} catch ( \Exception $e ) {
PRAutoBlogger_Logger::instance()->error( 'Manual generation FAILED: ' . $e->getMessage(), 'pipeline' );
} catch ( \Throwable $e ) {
PRAutoBlogger_Logger::instance()->error(
sprintf( 'Manual generation %s: %s', get_class( $e ), $e->getMessage() ),
'pipeline'
);
wp_send_json_error( [ 'message' => $e->getMessage() ] );
} finally {
$this->release_generation_lock();
@@ -156,9 +165,9 @@ class PRAutoBlogger_Executor {
}
wp_send_json_success( $result );
} catch ( \Exception $e ) {
} catch ( \Throwable $e ) {
PRAutoBlogger_Logger::instance()->error(
'Retroactive image gen failed for post ' . $post_id . ': ' . $e->getMessage(),
sprintf( 'Retroactive image gen %s for post %d: %s', get_class( $e ), $post_id, $e->getMessage() ),
'image_pipeline'
);
wp_send_json_error( [ 'message' => $e->getMessage() ] );

View File

@@ -221,9 +221,9 @@ class PRAutoBlogger_Image_Pipeline {
'attachment_id' => $attachment_id,
'cost_usd' => $image_data['cost_usd'],
];
} catch ( \Exception $e ) {
} catch ( \Throwable $e ) {
PRAutoBlogger_Logger::instance()->error(
'Image A generation failed: ' . $e->getMessage(),
sprintf( 'Image A %s: %s', get_class( $e ), $e->getMessage() ),
'image_pipeline'
);
@@ -287,9 +287,9 @@ class PRAutoBlogger_Image_Pipeline {
'attachment_id' => $attachment_id,
'cost_usd' => $image_data['cost_usd'],
];
} catch ( \Exception $e ) {
} catch ( \Throwable $e ) {
PRAutoBlogger_Logger::instance()->error(
'Image B generation failed: ' . $e->getMessage(),
sprintf( 'Image B %s: %s', get_class( $e ), $e->getMessage() ),
'image_pipeline'
);

View File

@@ -173,10 +173,10 @@ PROMPT;
if ( '' !== $scene ) {
return $scene;
}
} catch ( \Exception $e ) {
} catch ( \Throwable $e ) {
// LLM failure is not fatal — fall back to rule-based synthesis.
PRAutoBlogger_Logger::instance()->warning(
'Image prompt LLM rewrite failed, using fallback: ' . $e->getMessage(),
sprintf( 'Image prompt LLM rewrite %s, using fallback: %s', get_class( $e ), $e->getMessage() ),
'image_prompt_builder'
);
}

View File

@@ -124,8 +124,8 @@ class PRAutoBlogger_Pipeline_Runner {
$rejected++;
PRAutoBlogger_Logger::instance()->info( 'Article rejected by editor: ' . $idea->get_topic(), 'pipeline' );
}
} catch ( \Exception $e ) {
PRAutoBlogger_Logger::instance()->error( 'Failed to generate article for topic "' . $idea->get_topic() . '": ' . $e->getMessage(), 'pipeline' );
} catch ( \Throwable $e ) {
PRAutoBlogger_Logger::instance()->error( sprintf( 'Article generation %s for "%s": %s', get_class( $e ), $idea->get_topic(), $e->getMessage() ), 'pipeline' );
// Continue with next idea — don't let one failure stop the batch.
}
}

View File

@@ -168,8 +168,13 @@ class PRAutoBlogger_Post_Assembler {
'publisher'
);
}
} catch ( \Exception $e ) {
PRAutoBlogger_Logger::instance()->warning( 'Image pipeline exception for post ' . $post_id . ': ' . $e->getMessage(), 'publisher' );
} catch ( \Throwable $e ) {
// Catch \Throwable (not just \Exception) so PHP 8 TypeError/Error
// doesn't kill the process silently without any log entry.
PRAutoBlogger_Logger::instance()->error(
sprintf( 'Image pipeline %s for post %d: %s', get_class( $e ), $post_id, $e->getMessage() ),
'publisher'
);
}
}
}

View File

@@ -48,8 +48,8 @@ class PRAutoBlogger_Source_Collector {
sprintf( 'Collected %d items from %s (%d new).', count( $data ), $source_type, $inserted ),
'collector'
);
} catch ( \Exception $e ) {
PRAutoBlogger_Logger::instance()->error( "Collection from {$source_type} FAILED: " . $e->getMessage(), 'collector' );
} catch ( \Throwable $e ) {
PRAutoBlogger_Logger::instance()->error( sprintf( 'Collection %s from %s: %s', get_class( $e ), $source_type, $e->getMessage() ), 'collector' );
// Continue with other sources — one failure shouldn't stop everything.
}
}

View File

@@ -128,10 +128,11 @@ class PRAutoBlogger_Reddit_Provider implements PRAutoBlogger_Source_Provider_Int
sprintf( 'Reddit r/%s: fetched %d items', $subreddit, $added ),
'reddit'
);
} catch ( \Exception $e ) {
} catch ( \Throwable $e ) {
PRAutoBlogger_Logger::instance()->error(
sprintf(
'Reddit: Failed to collect from r/%s: %s',
'Reddit: %s collecting from r/%s: %s',
get_class( $e ),
$subreddit,
$e->getMessage()
),

View File

@@ -8,7 +8,7 @@ declare(strict_types=1);
* Plugin Name: PRAutoBlogger
* Plugin URI: https://peptiderepo.com/prautoblogger
* Description: Monitors social media for trending topics, generates SEO-friendly blog posts using AI, and publishes them on a daily schedule with full cost tracking and self-improvement metrics.
* Version: 0.2.6
* Version: 0.2.7
* Requires at least: 6.0
* Requires PHP: 7.4
* Author: PeptideRepo
@@ -35,7 +35,7 @@ if ( ! defined( 'ABSPATH' ) ) {
| and limits without magic strings.
*/
define( 'PRAUTOBLOGGER_VERSION', '0.2.6' );
define( 'PRAUTOBLOGGER_VERSION', '0.2.7' );
define( 'PRAUTOBLOGGER_DB_VERSION', '1.1.0' );
define( 'PRAUTOBLOGGER_PLUGIN_FILE', __FILE__ );
define( 'PRAUTOBLOGGER_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );