Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 53 additions & 15 deletions src/wp-includes/ai-client/class-wp-ai-client-prompt-builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@
*/

use WordPress\AiClient\Builders\PromptBuilder;
use WordPress\AiClient\Common\Exception\InvalidArgumentException;
use WordPress\AiClient\Common\Exception\TokenLimitReachedException;
use WordPress\AiClient\Files\DTO\File;
use WordPress\AiClient\Files\Enums\FileTypeEnum;
use WordPress\AiClient\Files\Enums\MediaOrientationEnum;
use WordPress\AiClient\Messages\DTO\Message;
use WordPress\AiClient\Messages\DTO\MessagePart;
use WordPress\AiClient\Messages\Enums\ModalityEnum;
use WordPress\AiClient\Providers\Http\DTO\RequestOptions;
use WordPress\AiClient\Providers\Http\Exception\ClientException;
use WordPress\AiClient\Providers\Http\Exception\NetworkException;
use WordPress\AiClient\Providers\Http\Exception\ServerException;
use WordPress\AiClient\Providers\Models\Contracts\ModelInterface;
use WordPress\AiClient\Providers\Models\DTO\ModelConfig;
use WordPress\AiClient\Providers\Models\Enums\CapabilityEnum;
Expand Down Expand Up @@ -179,13 +184,7 @@ public function __construct( ProviderRegistry $registry, $prompt = null ) {
$this->builder = new PromptBuilder( $registry, $prompt );
} catch ( Exception $e ) {
$this->builder = new PromptBuilder( $registry );
$this->error = new WP_Error(
'prompt_builder_error',
$e->getMessage(),
array(
'exception_class' => get_class( $e ),
)
);
$this->error = $this->exception_to_wp_error( $e );
}

/**
Expand Down Expand Up @@ -311,7 +310,7 @@ public function __call( string $name, array $arguments ) {
'prompt_prevented',
__( 'Prompt execution was prevented by a filter.' ),
array(
'exception_class' => 'WP_AI_Client_Prompt_Prevented',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for reviewers: This class doesn't exist, it was pointless and confusing to include this reference here just for consistency. Unlike the other WP_Error objects, this one is not based on an exception.

'status' => 503,
)
);

Expand All @@ -333,13 +332,7 @@ public function __call( string $name, array $arguments ) {

return $result;
} catch ( Exception $e ) {
$this->error = new WP_Error(
'prompt_builder_error',
$e->getMessage(),
array(
'exception_class' => get_class( $e ),
)
);
$this->error = $this->exception_to_wp_error( $e );

if ( self::is_generating_method( $name ) ) {
return $this->error;
Expand All @@ -348,6 +341,51 @@ public function __call( string $name, array $arguments ) {
}
}

/**
* Converts an exception into a WP_Error with a structured error code and message.
*
* This method maps different exception types to specific WP_Error codes and HTTP status codes.
* The presence of the status codes means these WP_Error objects can be easily used in REST API responses
* or other contexts where HTTP semantics are relevant.
*
* @since 7.0.0
*
* @param Exception $e The exception to convert.
* @return WP_Error The resulting WP_Error object.
*/
private function exception_to_wp_error( Exception $e ): WP_Error {
if ( $e instanceof NetworkException ) {
$error_code = 'prompt_network_error';
$status_code = 503;
} elseif ( $e instanceof ClientException ) {
// `ClientException` uses HTTP status codes as exception codes, so we can rely on them.
$error_code = 'prompt_client_error';
$status_code = $e->getCode() ? $e->getCode() : 400;
} elseif ( $e instanceof ServerException ) {
// `ServerException` uses HTTP status codes as exception codes, so we can rely on them.
$error_code = 'prompt_upstream_server_error';
$status_code = $e->getCode() ? $e->getCode() : 500;
} elseif ( $e instanceof TokenLimitReachedException ) {
$error_code = 'prompt_token_limit_reached';
$status_code = 400;
} elseif ( $e instanceof InvalidArgumentException ) {
$error_code = 'prompt_invalid_argument';
$status_code = 400;
} else {
$error_code = 'prompt_builder_error';
$status_code = 500;
}

return new WP_Error(
$error_code,
$e->getMessage(),
array(
'status' => $status_code,
'exception_class' => get_class( $e ),
)
);
}

/**
* Checks if a method name is a support check method (is_supported*).
*
Expand Down
Loading
Loading