🐛 fix(core): return JSON-RPC protocol errors
This commit is contained in:
@@ -14,6 +14,10 @@ def frame(message: dict) -> bytes:
|
||||
return f"Content-Length: {len(body)}\r\n\r\n".encode("ascii") + body
|
||||
|
||||
|
||||
def raw_frame(body: bytes) -> bytes:
|
||||
return f"Content-Length: {len(body)}\r\n\r\n".encode("ascii") + body
|
||||
|
||||
|
||||
def read_messages(data: bytes) -> list[dict]:
|
||||
messages = []
|
||||
offset = 0
|
||||
@@ -169,12 +173,48 @@ def assert_lifecycle(server: Path) -> None:
|
||||
client.kill()
|
||||
|
||||
|
||||
def assert_json_rpc_errors(server: Path) -> None:
|
||||
payload = b"".join([
|
||||
raw_frame(b'{"jsonrpc":"2.0",'),
|
||||
raw_frame(b"[]"),
|
||||
raw_frame(b'{"jsonrpc":"1.0","id":7,"method":"initialize"}'),
|
||||
frame({
|
||||
"jsonrpc": "2.0",
|
||||
"id": 8,
|
||||
"method": "initialize",
|
||||
"params": {},
|
||||
}),
|
||||
frame({"jsonrpc": "2.0", "id": 9, "method": "missing/method"}),
|
||||
frame({"jsonrpc": "2.0", "id": 10, "method": "shutdown"}),
|
||||
frame({"jsonrpc": "2.0", "method": "exit"}),
|
||||
])
|
||||
result = run_raw(server, payload)
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError("JSON-RPC error sequence should shut down cleanly")
|
||||
|
||||
responses = read_messages(result.stdout)
|
||||
if responses[0].get("id", "missing") is not None:
|
||||
raise RuntimeError(
|
||||
f"ParseError response should use a null id: {responses[0]!r}")
|
||||
if responses[0].get("error", {}).get("code") != -32700:
|
||||
raise RuntimeError("Malformed JSON should return ParseError")
|
||||
if responses[1].get("id", "missing") is not None:
|
||||
raise RuntimeError("InvalidRequest response should use a null id")
|
||||
if responses[1].get("error", {}).get("code") != -32600:
|
||||
raise RuntimeError("A non-object JSON value should return InvalidRequest")
|
||||
if response_by_id(result.stdout, 7).get("error", {}).get("code") != -32600:
|
||||
raise RuntimeError("jsonrpc other than 2.0 should return InvalidRequest")
|
||||
if response_by_id(result.stdout, 9).get("error", {}).get("code") != -32601:
|
||||
raise RuntimeError("Unknown request method should return MethodNotFound")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--server", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
assert_lifecycle(args.server)
|
||||
assert_json_rpc_errors(args.server)
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user