Skip to content

Commit

Permalink
Merge pull request #124 from alleyinteractive/hotfix/serialize-exception
Browse files Browse the repository at this point in the history
Fix a serialization error when using an exception in context
  • Loading branch information
srtfisher authored Jul 2, 2024
2 parents d172a24 + 3604a76 commit d87e180
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
This library adheres to [Semantic Versioning](https://semver.org/) and [Keep a
CHANGELOG](https://keepachangelog.com/en/1.0.0/).

## 2.4.3 - 2024-07-02

- Fix a serialization of closure error when using an exception in a log's context.

## 2.4.2 - 2024-06-28

- Fix an incorrectly named variable in the `Post_Handler` class.
Expand Down
40 changes: 39 additions & 1 deletion inc/handler/class-post-handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Monolog\Logger;
use Spatie\Backtrace\Backtrace;
use Spatie\Backtrace\Frame as SpatieFrame;
use Throwable;

/**
* Post Log Handler
Expand Down Expand Up @@ -197,6 +198,27 @@ public function process_queue() {
);

if ( ! empty( $log_post_id ) ) {
// Sanitize the context to prevent an accidental serialize error. When serializing
// an exception, PHP will throw a Serialization of 'Closure' is not allowed error.
if ( ! empty( $log['context'] ) && is_array( $log['context'] ) ) {
$log['context'] = array_map(
function ( mixed $value ) {
if ( $value instanceof Throwable ) {
if ( method_exists( $value, '__toString' ) ) {
return $value->__toString();
} elseif ( method_exists( $value, 'getTraceAsString' ) ) {
return $value->getTraceAsString();
}

return $value->getMessage();
}

return $value;
},
$log['context'],
);
}

\update_post_meta( $log_post_id, '_logger_record', $log );

$this->assign_terms( $log_post_id, $level, static::TAXONOMY_LOG_LEVEL );
Expand All @@ -221,6 +243,8 @@ public function process_queue() {
* Process the queue when shutting down.
*
* Ensure that all logs are properly saved when shutting down (if any are left).
*
* @throws Throwable If an error occurs while processing the queue during testing.
*/
public function process_queue_shutdown() {
if ( empty( $this->queue ) ) {
Expand All @@ -232,7 +256,21 @@ public function process_queue_shutdown() {
\switch_to_blog( $this->original_site_id ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.switch_to_blog_switch_to_blog
}

$this->process_queue();
try {
$this->process_queue();
} catch ( Throwable $e ) {
// Throw the exception if testing.
if ( defined( 'MANTLE_IS_TESTING' ) && MANTLE_IS_TESTING ) {
throw $e;
}

// In the event of any error, log to the actual error log if an exception
// is thrown to prevent an exception from bubbling up.
error_log( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
"AI Logger: Error processing queue during shutdown: {$e->getMessage()}",
E_ERROR,
);
}

if ( $switching ) {
\restore_current_blog();
Expand Down
25 changes: 25 additions & 0 deletions tests/LoggerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
namespace AI_Logger\Tests;

use AI_Logger\AI_Logger;
use AI_Logger\Handler\Post_Handler;
use Mantle\Testkit\Test_Case;
use Monolog\Handler\NullHandler;
use Monolog\Handler\TestHandler;
Expand Down Expand Up @@ -130,6 +131,30 @@ public function test_with_context() {
)
);
}

public function test_serialize_exception() {
$logger = ai_logger()->with_handlers(
[
$handler = new Post_Handler(),
]
);

$logger->error(
'This is a test',
[
'error' => new \InvalidArgumentException( 'Test Exception', 500 ),
]
);

$handler->process_queue_shutdown();

$this->assertPostExists(
[
'post_title' => 'This is a test',
'post_type' => 'ai_log',
]
);
}
}


Expand Down

0 comments on commit d87e180

Please sign in to comment.