[Schema] Omit the id of an error response that never had one (#442)

* [Schema] Omit the id of an error response that never had one

An error response whose id could not be read sent `"id": ""`, which claims
the peer issued a request with an empty-string id - a different statement
from "the id could not be read". JSON-RPC spells the latter as a null id,
and a receiver that cannot read the id is exactly the case the code covers.

[BC Break] Error::$id accepts null and getId() may return it. All the for*()
factories default to null, fromArray() accepts a missing or explicitly-null
id, and the member is omitted from the serialized form when absent.

* Guard null response id in Client/Server Protocol handlers

Also fix Error::jsonSerialize()'s phpdoc: data belongs inside error, not beside it.
This commit is contained in:
Christopher Hertel 2026-08-18 15:24:19 +02:00 • committed by GitHub
commit 5041caf77a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -99,6 +99,19 @@ final class ProtocolTest extends TestCase
yield 'modern revision' => [ProtocolVersion::V2026_07_28->value];
}
#[TestDox('logs and ignores an id-less error response instead of crashing on it')]
public function testIgnoresIdLessErrorResponse(): void
{
$protocol = new Protocol(logger: $logger = new CollectingLogger());
$protocol->processMessage(json_encode([
'jsonrpc' => MessageInterface::JSONRPC_VERSION,
'error' => ['code' => -32700, 'message' => 'Parse error'],
], \JSON_THROW_ON_ERROR));
$this->assertCount(1, $logger->warnings);
}
private function createConfiguration(ProtocolVersion $protocolVersion): Configuration
{
return new Configuration(