Skip to content

Commit 9ce5419

Browse files
committed
AI: Catch exceptions in WP_AI_Client_Prompt_Builder::__construct().
Exceptions were already caught and transformed into `WP_Error` objects in all instance methods of `WP_AI_Client_Prompt_Builder`, but not in the constructor. This meant that if an exception was thrown during construction, it would not be caught and would cause a fatal error instead of returning a `WP_Error` object. Props gziolo. See #64591. git-svn-id: https://develop.svn.wordpress.org/trunk@61787 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 7dcc5c3 commit 9ce5419

2 files changed

Lines changed: 49 additions & 28 deletions

File tree

src/wp-includes/ai-client/class-wp-ai-client-prompt-builder.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,18 @@ class WP_AI_Client_Prompt_Builder {
165165
* conversations. Default null.
166166
*/
167167
public function __construct( ProviderRegistry $registry, $prompt = null ) {
168-
$this->builder = new PromptBuilder( $registry, $prompt );
168+
try {
169+
$this->builder = new PromptBuilder( $registry, $prompt );
170+
} catch ( Exception $e ) {
171+
$this->builder = new PromptBuilder( $registry );
172+
$this->error = new WP_Error(
173+
'prompt_builder_error',
174+
$e->getMessage(),
175+
array(
176+
'exception_class' => get_class( $e ),
177+
)
178+
);
179+
}
169180

170181
/**
171182
* Filters the default request timeout in seconds for AI Client HTTP requests.

tests/phpunit/tests/ai-client/wpAiClientPromptBuilder.php

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,22 +1347,15 @@ public function test_validate_messages_non_user_last_returns_wp_error() {
13471347
/**
13481348
* Tests parseMessage with empty string returns WP_Error on termination.
13491349
*
1350-
* The SDK constructor throws immediately for empty strings, so the exception
1351-
* is caught in the constructor and stored.
1352-
*
13531350
* @ticket 64591
13541351
*/
13551352
public function test_parse_message_empty_string_returns_wp_error() {
1356-
// The empty string exception is thrown by the SDK's PromptBuilder constructor,
1357-
// which happens before our __call() error handling. We must catch it manually.
1358-
try {
1359-
$builder = new WP_AI_Client_Prompt_Builder( $this->registry, ' ' );
1360-
// If we get here, the SDK didn't throw. Test would need adjusting.
1361-
$result = $builder->generate_result();
1362-
$this->assertWPError( $result );
1363-
} catch ( InvalidArgumentException $e ) {
1364-
$this->assertStringContainsString( 'Cannot create a message from an empty string', $e->getMessage() );
1365-
}
1353+
$builder = new WP_AI_Client_Prompt_Builder( $this->registry, ' ' );
1354+
$result = $builder->generate_result();
1355+
1356+
$this->assertWPError( $result );
1357+
$this->assertSame( 'prompt_builder_error', $result->get_error_code() );
1358+
$this->assertStringContainsString( 'Cannot create a message from an empty string', $result->get_error_message() );
13661359
}
13671360

13681361
/**
@@ -1371,13 +1364,12 @@ public function test_parse_message_empty_string_returns_wp_error() {
13711364
* @ticket 64591
13721365
*/
13731366
public function test_parse_message_empty_array_returns_wp_error() {
1374-
try {
1375-
$builder = new WP_AI_Client_Prompt_Builder( $this->registry, array() );
1376-
$result = $builder->generate_result();
1377-
$this->assertWPError( $result );
1378-
} catch ( InvalidArgumentException $e ) {
1379-
$this->assertStringContainsString( 'Cannot create a message from an empty array', $e->getMessage() );
1380-
}
1367+
$builder = new WP_AI_Client_Prompt_Builder( $this->registry, array() );
1368+
$result = $builder->generate_result();
1369+
1370+
$this->assertWPError( $result );
1371+
$this->assertSame( 'prompt_builder_error', $result->get_error_code() );
1372+
$this->assertStringContainsString( 'Cannot create a message from an empty array', $result->get_error_message() );
13811373
}
13821374

13831375
/**
@@ -1386,13 +1378,31 @@ public function test_parse_message_empty_array_returns_wp_error() {
13861378
* @ticket 64591
13871379
*/
13881380
public function test_parse_message_invalid_type_returns_wp_error() {
1389-
try {
1390-
$builder = new WP_AI_Client_Prompt_Builder( $this->registry, 123 );
1391-
$result = $builder->generate_result();
1392-
$this->assertWPError( $result );
1393-
} catch ( InvalidArgumentException $e ) {
1394-
$this->assertStringContainsString( 'Input must be a string, MessagePart, MessagePartArrayShape', $e->getMessage() );
1395-
}
1381+
$builder = new WP_AI_Client_Prompt_Builder( $this->registry, 123 );
1382+
$result = $builder->generate_result();
1383+
1384+
$this->assertWPError( $result );
1385+
$this->assertSame( 'prompt_builder_error', $result->get_error_code() );
1386+
$this->assertStringContainsString( 'Input must be a string, MessagePart, MessagePartArrayShape', $result->get_error_message() );
1387+
}
1388+
1389+
/**
1390+
* Tests that wp_ai_client_prompt() with an empty string does not throw.
1391+
*
1392+
* Constructor exceptions are caught and surfaced as WP_Error from
1393+
* generating methods, consistent with the __call() wrapping behavior.
1394+
*
1395+
* @ticket 64591
1396+
*/
1397+
public function test_wp_ai_client_prompt_empty_string_returns_wp_error() {
1398+
$builder = wp_ai_client_prompt( ' ' );
1399+
1400+
$this->assertInstanceOf( WP_AI_Client_Prompt_Builder::class, $builder );
1401+
1402+
$result = $builder->generate_text();
1403+
1404+
$this->assertWPError( $result );
1405+
$this->assertSame( 'prompt_builder_error', $result->get_error_code() );
13961406
}
13971407

13981408
/**

0 commit comments

Comments
 (0)