Description
The AI Request Logs screen records every provider request that gets an HTTP response as success, whatever the status code. A 503 or 429 from the provider shows as a green "✓ success" row. Neither the status code nor the provider's error message is stored. As a result, the log looks healthy while a feature is failing every time.
In Logging_Http_Transporter::send() (includes/Logging/Logging_Http_Transporter.php, unchanged between 1.3.0 and trunk), $status starts as 'success' and changes only in the catch ( Throwable $e ) branch:
$status = 'success';
try {
$response = $this->transporter->send( $request, $options );
$log_data = $this->extract_response_data( $response, $log_data );
return $response;
} catch ( Throwable $e ) {
$status = 'error';
$error_msg = $e->getMessage();
throw $e;
} finally {
$log_data['status'] = $status;
$log_data['error_message'] = $error_msg;
$this->log_manager->log( $log_data );
}
The SDK's HttpTransporter::send() throws only for PSR-18 network or client exceptions. A non-2xx response comes back as an ordinary Response. The provider rejects it later, after the log row has already been written. For example, GoogleTextGenerationModel::generateTextResult() calls ResponseUtil::throwIfNotSuccessful( $response ) right after send() returns. That throws a ServerException, which reaches the user as prompt_upstream_server_error, but the log already says success.
A second, smaller problem appears on the same rows. Log_Data_Extractor::detect_request_kind() returns metadata for any path containing /models/. Every Gemini generation URL has the form .../v1beta/models/{model}:generateContent, so all Google text requests are labeled Request Kind: Metadata.
Step-by-step reproduction instructions
- Connect the Google provider and enable Request Logging and Image Generation.
- Trigger a request that the provider rejects. The easiest way is to exceed a free-tier quota, which returns 429. I also hit a deterministic 503 from
gemini-3.6-flash on some prompt content.
- The editor shows the error, e.g.
{"code":"prompt_upstream_server_error","message":"Service Unavailable (503) - This model is currently experiencing high demand. ...","data":{"status":503,"exception_class":"WordPress\\AiClient\\Providers\\Http\\Exception\\ServerException"}}
- Open Tools > AI Request Logs and view the matching row.
Expected: status error, the HTTP status code, and the provider's error message.
Actual: ✓ success, no error message, no token counts, no output preview, and Request Kind Metadata.
In my case the 503 came back on every attempt over several days. I only found the cause by capturing the request body and replaying it outside the plugin. If the log had shown error with the 503 message, I wouldn't have needed to.
Suggested fix
Response already provides isSuccessful() and getStatusCode(). After a response comes back:
$response = $this->transporter->send( $request, $options );
$log_data = $this->extract_response_data( $response, $log_data );
if ( ! $response->isSuccessful() ) {
$status = 'error';
$error_msg = sprintf( 'HTTP %d', $response->getStatusCode() );
$data = $response->getData();
if ( isset( $data['error']['message'] ) && is_string( $data['error']['message'] ) ) {
$error_msg .= ': ' . $data['error']['message'];
}
}
Storing the status code in its own column (or in context) would also make these rows filterable. For detect_request_kind(), checking for a :generateContent / :streamGenerateContent suffix before the /models/ rule would fix the Gemini mislabel.
Related
Screenshots, screen recording, code snippet
No response
Environment info
- WordPress 7.1
- AI plugin 1.3.0, AI Provider for Google 1.1.1
- PHP 8.5
Please confirm that you have searched existing issues in the repo.
Please confirm that you have tested with all plugins deactivated except the AI plugin.
Please confirm which theme type you used for testing.
Description
The AI Request Logs screen records every provider request that gets an HTTP response as
success, whatever the status code. A 503 or 429 from the provider shows as a green "✓ success" row. Neither the status code nor the provider's error message is stored. As a result, the log looks healthy while a feature is failing every time.In
Logging_Http_Transporter::send()(includes/Logging/Logging_Http_Transporter.php, unchanged between 1.3.0 and trunk),$statusstarts as'success'and changes only in thecatch ( Throwable $e )branch:The SDK's
HttpTransporter::send()throws only for PSR-18 network or client exceptions. A non-2xx response comes back as an ordinaryResponse. The provider rejects it later, after the log row has already been written. For example,GoogleTextGenerationModel::generateTextResult()callsResponseUtil::throwIfNotSuccessful( $response )right aftersend()returns. That throws aServerException, which reaches the user asprompt_upstream_server_error, but the log already sayssuccess.A second, smaller problem appears on the same rows.
Log_Data_Extractor::detect_request_kind()returnsmetadatafor any path containing/models/. Every Gemini generation URL has the form.../v1beta/models/{model}:generateContent, so all Google text requests are labeled Request Kind: Metadata.Step-by-step reproduction instructions
gemini-3.6-flashon some prompt content.{"code":"prompt_upstream_server_error","message":"Service Unavailable (503) - This model is currently experiencing high demand. ...","data":{"status":503,"exception_class":"WordPress\\AiClient\\Providers\\Http\\Exception\\ServerException"}}Expected: status
error, the HTTP status code, and the provider's error message.Actual:
✓ success, no error message, no token counts, no output preview, and Request KindMetadata.In my case the 503 came back on every attempt over several days. I only found the cause by capturing the request body and replaying it outside the plugin. If the log had shown
errorwith the 503 message, I wouldn't have needed to.Suggested fix
Responsealready providesisSuccessful()andgetStatusCode(). After a response comes back:Storing the status code in its own column (or in
context) would also make these rows filterable. Fordetect_request_kind(), checking for a:generateContent/:streamGenerateContentsuffix before the/models/rule would fix the Gemini mislabel.Related
Logging_Http_Transporter::send()(event-listener fallback for providers that bypass the transporter), so the two changes will touch the same method.Screenshots, screen recording, code snippet
No response
Environment info
Please confirm that you have searched existing issues in the repo.
Please confirm that you have tested with all plugins deactivated except the AI plugin.
Please confirm which theme type you used for testing.