From 19688640733b5e3b2803bd175478d8e082b9e9e4 Mon Sep 17 00:00:00 2001 From: peptiderepo Date: Sat, 18 Apr 2026 10:12:06 +0700 Subject: [PATCH] fix: widen all catch blocks from \Exception to \Throwable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- includes/class-executor.php | 25 +++++++++++++------- includes/core/class-image-pipeline.php | 8 +++---- includes/core/class-image-prompt-builder.php | 4 ++-- includes/core/class-pipeline-runner.php | 4 ++-- includes/core/class-post-assembler.php | 9 +++++-- includes/core/class-source-collector.php | 4 ++-- includes/providers/class-reddit-provider.php | 5 ++-- prautoblogger.php | 4 ++-- 8 files changed, 39 insertions(+), 24 deletions(-) diff --git a/includes/class-executor.php b/includes/class-executor.php index d2944b3..f474b6e 100644 --- a/includes/class-executor.php +++ b/includes/class-executor.php @@ -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() ] ); diff --git a/includes/core/class-image-pipeline.php b/includes/core/class-image-pipeline.php index b5a9e59..f23b82c 100644 --- a/includes/core/class-image-pipeline.php +++ b/includes/core/class-image-pipeline.php @@ -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' ); diff --git a/includes/core/class-image-prompt-builder.php b/includes/core/class-image-prompt-builder.php index fcd9366..b35183f 100644 --- a/includes/core/class-image-prompt-builder.php +++ b/includes/core/class-image-prompt-builder.php @@ -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' ); } diff --git a/includes/core/class-pipeline-runner.php b/includes/core/class-pipeline-runner.php index c747916..39256e4 100755 --- a/includes/core/class-pipeline-runner.php +++ b/includes/core/class-pipeline-runner.php @@ -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. } } diff --git a/includes/core/class-post-assembler.php b/includes/core/class-post-assembler.php index 4f02041..0d59fbf 100644 --- a/includes/core/class-post-assembler.php +++ b/includes/core/class-post-assembler.php @@ -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' + ); } } } diff --git a/includes/core/class-source-collector.php b/includes/core/class-source-collector.php index 7cc4f6f..5ffe904 100755 --- a/includes/core/class-source-collector.php +++ b/includes/core/class-source-collector.php @@ -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. } } diff --git a/includes/providers/class-reddit-provider.php b/includes/providers/class-reddit-provider.php index fb38c9c..d1dd3f1 100755 --- a/includes/providers/class-reddit-provider.php +++ b/includes/providers/class-reddit-provider.php @@ -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() ), diff --git a/prautoblogger.php b/prautoblogger.php index 5c6de94..0a35e05 100644 --- a/prautoblogger.php +++ b/prautoblogger.php @@ -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__ ) );