Repository navigation
refactor(grpc): improve Parser::parseResponse return value format - #7653
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors the Parser::parseResponse method to return a more standardized format using stdClass instead of a mixed-type array. The change replaces the old three-element array format [message, code, response] with a two-element array [message, statusObject] where the status object contains code, details, and metadata fields.
Key Changes:
- Replaced
Grpc\StringifyAbleimport withstdClass - Updated return type annotation to specify structured stdClass status object
- Standardized all return paths to use consistent stdClass format with
code,details, andmetadatafields
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/grpc/src/Parser.php | Refactored parseResponse method to return structured stdClass status object instead of mixed array elements |
| CHANGELOG-3.2.md | Added changelog entry documenting the improvement |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return [ | ||
| self::deserializeMessage($deserialize, $response->data ?? ''), | ||
| self::statusFromResponse($response), | ||
| $response, | ||
| ]; |
There was a problem hiding this comment.
Critical error handling logic has been removed without replacement. The old implementation checked for:
- Invalid HTTP status codes (via
isInvalidStatus()) - returning error when statusCode was not 0, 200, or 400 - Non-zero gRPC status codes (
grpc-status !== 0) - returning the gRPC error message
The new implementation only calls statusFromResponse() which only extracts grpc-status-details-bin header. This means:
- Invalid HTTP status codes are no longer detected or reported
- gRPC error status codes (from
grpc-statusheader) are not being checked or returned - Error messages from
grpc-messageheader are lost
The method now deserializes the response data unconditionally, even when there are errors, which could lead to deserialization failures or incorrect behavior. The error handling logic should be restored to properly validate the response before attempting deserialization.
- Replace Grpc\StringifyAble with stdClass for better standardization - Update return type annotation to be more explicit about the structure - Standardize all return paths to use consistent stdClass status object - Improve code readability and maintainability
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
…s codes and messages
…alize parameters in UnaryCall class
…streamId directly
…ethod in UnaryCall class
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (in_array($lowerKey, ['content-type', 'content-length', 'te'])) { | ||
| continue; | ||
| } | ||
| // 处理-bin结尾 metadata |
There was a problem hiding this comment.
[nitpick] The comment contains Chinese characters which may not be clear to all contributors. Consider translating to English: "Handle -bin suffixed metadata"
| // 处理-bin结尾 metadata | |
| // Handle -bin suffixed metadata |
| $status = new stdClass(); | ||
| $status->code = 0; | ||
| $status->details = 'OK'; | ||
| $status->metadata = []; |
There was a problem hiding this comment.
The metadata is initialized as an empty array on line 57, but should be initialized to match the documented return type. According to the PHPDoc annotations, metadata should be typed as null|Http2Response in the return type (lines 23, 35, 50), not as an array. Either change line 57 to $status->metadata = null; or update the PHPDoc to reflect that metadata is an array of parsed headers.
| $status->metadata = []; | |
| $status->metadata = null; |
| if (str_starts_with($lowerKey, 'grpc-') && $lowerKey !== 'grpc-status-details-bin') { | ||
| continue; | ||
| } | ||
| // 忽略http2预留伪头 |
There was a problem hiding this comment.
[nitpick] The comment contains Chinese characters which may not be clear to all contributors. Consider translating to English: "Ignore HTTP/2 reserved pseudo-headers"
| // 忽略http2预留伪头 | |
| // Ignore HTTP/2 reserved pseudo-headers |
| if (str_starts_with($lowerKey, ':')) { | ||
| continue; | ||
| } | ||
| // 忽略 HTTP/2 传输层头部 |
There was a problem hiding this comment.
[nitpick] The comment contains Chinese characters which may not be clear to all contributors. Consider translating to English: "Ignore HTTP/2 transport layer headers"
| // 忽略 HTTP/2 传输层头部 | |
| // Ignore HTTP/2 transport layer headers |
| }, $this->options['retry_interval'] ?? 100); | ||
| return Parser::parseResponse($this->recv($streamId), $deserialize); | ||
|
|
||
| return new UnaryCall($this, $streamId, $deserialize); |
There was a problem hiding this comment.
This change breaks existing tests. The method now returns a UnaryCall object instead of directly parsing and returning the response. However, BaseClientTest.php expects _simpleRequest to return a numeric value (stream ID) in tests like testGrpcClientReconnect() which calls $this->assertGreaterThan(0, $client->sayHello()). Since sayHello() returns the result of _simpleRequest, these tests will fail. The tests need to be updated to call ->wait() on the returned UnaryCall object, or test coverage should be added for the new return behavior.
| $status->code = 0; | ||
| $status->details = 'OK'; | ||
| $status->metadata = []; | ||
| $status->rawResponse = $response; |
There was a problem hiding this comment.
The rawResponse property is being added to the status object but is not documented in the return type annotation. The PHPDoc at line 35 and 50 should include rawResponse in the stdClass structure definition: stdClass{code:int,details:string,metadata:array,rawResponse:null|Http2Response}
|
|
||
| foreach ($response->headers as $key => $value) { | ||
| $lowerKey = strtolower($key); | ||
| // 忽略grpc官方预留,将grpc-status-details-bin保留,可解析为Google\Rpc\Status |
There was a problem hiding this comment.
[nitpick] The comment contains Chinese characters which may not be clear to all contributors. Consider translating to English: "Ignore official gRPC reserved headers, keep grpc-status-details-bin which can be parsed as Google\Rpc\Status"
| // 忽略grpc官方预留,将grpc-status-details-bin保留,可解析为Google\Rpc\Status | |
| // Ignore official gRPC reserved headers, keep grpc-status-details-bin which can be parsed as Google\Rpc\Status |
Co-authored-by: Copilot <[email protected]>
Summary
Parser::parseResponsemethod to use a more standardized approachGrpc\StringifyAbledependency withstdClassfor better compatibilityChanges Made
use Grpc\StringifyAble;withuse stdClass;array{0:null|Message,1:stdClass{code:int,details:string,metadata:null|Http2Response}}code: Error/status codedetails: Descriptive messagemetadata: Response metadataTest Plan