Plugin Directory

Changeset 3424471


Ignore:
Timestamp:
12/21/2025 06:26:34 AM (3 months ago)
Author:
manovermachine
Message:

Version 1.3.15: Critical timezone fix for watchdog alerts + time validation

CRITICAL FIX:

  • Fixed timezone bug causing false "watchdog detected missed run" alerts
  • Posts were being created successfully but watchdog couldn't find them
  • Affected users in all timezones (intermittent failures)

THE PROBLEM:

  • slot_time was logged using gmdate() (GMT/UTC timezone)
  • Watchdog searched using wp_date() (WordPress timezone)
  • 6-hour mismatch for Central timezone users (varies by timezone)
  • Watchdog's 5-minute tolerance check failed: abs(11:50 - 5:50) = 21,600 seconds > 300
  • Event was skipped even though it existed in database

WHY IT WAS INTERMITTENT:

  • Plugin has TWO event logging systems running in parallel
  • Old system (options table): Matches by time string - no timezone issues
  • New system (database table): Matches by timestamp - had timezone bug
  • Sometimes old system found event (worked), sometimes only new system had it (failed)

THE SOLUTION:

  • Changed slot_time logging from gmdate() to wp_date() with WordPress timezone
  • Now both logging and watchdog use same timezone
  • Modified /includes/class-scheduler.php line 173-175

BEFORE:

$slot_time = gmdate( 'Y-m-d H:i:s', strtotime( $hm ) );
Logged: "2025-11-11 11:50:00" (UTC) for 5:50 AM Central

AFTER:

$tz = wp_timezone();
$slot_time = wp_date( 'Y-m-d H:i:s', strtotime( $hm ), $tz );
Logs: "2025-11-11 05:50:00" (Central) for 5:50 AM Central

ADDITIONAL ENHANCEMENT:

  • Added time format validation for schedule settings
  • Supports 8 common formats: 6:00am, 6am, 6 AM, 18:00, 18, etc.
  • Clear error messages for invalid formats
  • Auto-converts all formats to HH:MM (24-hour) standard

VALIDATION EXAMPLES:

  • User enters "6pm" → Saved as "18:00" ✓
  • User enters "6:00 AM" → Saved as "06:00" ✓
  • User enters "6PM" → Error: "Invalid time format(s): 6PM. Please use formats like '6:00am', '6:00 AM', '18:00', or '6pm'" ✗

TECHNICAL CHANGES:

  • Modified /includes/class-scheduler.php: Fixed timezone in slot_time logging
  • Modified /includes/class-admin.php: Added time format validation (lines 1993-2036)
  • Added add_settings_error() for user feedback on invalid formats

BENEFITS:

  • ✅ Eliminates false "missed run" alerts completely
  • ✅ No user action required - fix applies automatically on next post run
  • ✅ Better UX with time format validation and helpful errors
  • ✅ Converts common time formats automatically
  • ✅ More reliable watchdog detection across all timezones

COMPATIBILITY:

  • Fix applies immediately on next scheduled post
  • No database migration needed
  • No settings changes required
  • Works with all timezones

USER IMPACT:

  • Users will stop receiving false watchdog alerts
  • Clear feedback when entering schedule times in invalid formats
  • More confidence in scheduled posting reliability
Location:
weather-write/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • weather-write/trunk/includes/class-openmeteo.php

    r3385542 r3424471  
    7474        $url = add_query_arg( $args, 'https://api.open-meteo.com/v1/forecast' );
    7575
    76         $response = wp_remote_get( $url, [ 'timeout' => 25, 'headers' => [ 'User-Agent' => 'WeatherWrite/1.0 (' . home_url() . ')', 'Accept' => 'application/json' ] ] );
    77         if ( is_wp_error( $response ) ) {
    78             return $response;
    79         }
    80 
    81         $code = wp_remote_retrieve_response_code( $response );
    82         $body = wp_remote_retrieve_body( $response );
     76        // Retry logic for improved reliability during slow API responses
     77        $max_attempts = 2;
     78        $attempt = 0;
     79        $response = null;
     80        $code = 0;
     81        $body = '';
     82       
     83        while ( $attempt < $max_attempts ) {
     84            $attempt++;
     85            // Use shorter timeout on first attempt (15s), longer on retry (25s)
     86            $timeout = ( $attempt === 1 ) ? 15 : 25;
     87            $response = wp_remote_get( $url, [ 'timeout' => $timeout, 'headers' => [ 'User-Agent' => 'WeatherWrite/1.0 (' . home_url() . ')', 'Accept' => 'application/json' ] ] );
     88           
     89            if ( is_wp_error( $response ) ) {
     90                // Network error or timeout - retry once
     91                if ( $attempt < $max_attempts ) {
     92                    error_log( "WeatherWrite: Open-Meteo error on attempt {$attempt}, retrying... Error: " . $response->get_error_message() );
     93                    sleep( 2 ); // Wait 2 seconds before retry
     94                    continue;
     95                }
     96                // Final attempt failed - return error
     97                return $response;
     98            }
     99           
     100            $code = wp_remote_retrieve_response_code( $response );
     101            $body = wp_remote_retrieve_body( $response );
     102           
     103            // Retry on 5xx server errors (503 Service Unavailable, 504 Gateway Timeout, etc.)
     104            if ( $code >= 500 && $code < 600 && $attempt < $max_attempts ) {
     105                error_log( "WeatherWrite: Open-Meteo HTTP {$code} on attempt {$attempt}, retrying..." );
     106                sleep( 2 ); // Wait 2 seconds before retry
     107                continue;
     108            }
     109           
     110            // Success or non-retryable error - break out
     111            break;
     112        }
     113       
    83114        if ( $code < 200 || $code >= 300 ) {
    84             return new WP_Error( 'openmeteo_http_error', 'Weather API error', [ 'status' => $code, 'body' => $body ] );
     115            return new WP_Error( 'openmeteo_http_error', 'Weather API error after ' . $attempt . ' attempts', [ 'status' => $code, 'body' => $body ] );
    85116        }
    86117
  • weather-write/trunk/includes/class-reintent.php

    r3385495 r3424471  
    6868        ];
    6969       
    70         // Retry logic for 504 Gateway Timeout errors
     70        // Retry logic for network errors and 5xx server errors
    7171        $max_attempts = 2;
    7272        $attempt = 0;
     
    8282                // Network error - retry once
    8383                if ( $attempt < $max_attempts ) {
    84                     error_log( "WeatherWrite: ChatGPT network error on attempt {$attempt}, retrying..." );
     84                    error_log( "WeatherWrite: ChatGPT network error on attempt {$attempt}, retrying... Error: " . $resp->get_error_message() );
    8585                    sleep( 2 ); // Wait 2 seconds before retry
    8686                    continue;
     
    9292            $body = wp_remote_retrieve_body( $resp );
    9393           
    94             // Retry on 504 Gateway Timeout
    95             if ( $code === 504 && $attempt < $max_attempts ) {
    96                 error_log( "WeatherWrite: ChatGPT 504 timeout on attempt {$attempt}, retrying..." );
     94            // Retry on all 5xx server errors (500, 502, 503, 504, etc.)
     95            if ( $code >= 500 && $code < 600 && $attempt < $max_attempts ) {
     96                error_log( "WeatherWrite: ChatGPT HTTP {$code} on attempt {$attempt}, retrying..." );
    9797                sleep( 2 ); // Wait 2 seconds before retry
    9898                continue;
  • weather-write/trunk/readme.txt

    r3424052 r3424471  
    44Requires at least: 6.5
    55Tested up to: 6.8
    6 Stable tag: 1.3.14
     6Stable tag: 1.3.15
    77License: GPLv2 or later
    88License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    8787
    8888== Changelog ==
     89
     90= 1.3.15 =
     91- ENHANCEMENT: Improved Open-Meteo API reliability with smart retry logic
     92- First attempt uses 15-second timeout for fast failure detection
     93- Automatic retry with 25-second timeout on network errors or 5xx server errors
     94- ENHANCEMENT: Enhanced ReIntent API retry logic to handle all 5xx server errors (not just 504)
     95- Both APIs now retry on network errors, timeouts, and server errors
     96- 2-second delay between retry attempts to allow transient issues to resolve
     97- Significantly reduces API failures during peak hours and service disruptions
     98- Better error logging for debugging retry attempts
    8999
    90100= 1.3.14 =
  • weather-write/trunk/weather-write.php

    r3424052 r3424471  
    33 * Plugin Name: Weather Write
    44 * Description: Generate and publish weather-aware posts with summaries, charts, images, alerts, SEO, and more — fully automated or on-demand.
    5  * Version: 1.3.14
     5 * Version: 1.3.15
    66 * Author: Mike Freeman - WeatherWrite
    77 * Plugin URI: https://www.weatherwrite.com/
Note: See TracChangeset for help on using the changeset viewer.