mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-17 15:24:40 +01:00
parse error
This commit is contained in:
@@ -76,6 +76,7 @@ export function isJsonRpcResponse(msg: IProtocolMessage): msg is IJsonRpcRespons
|
||||
|
||||
// ---- JSON-RPC error codes ---------------------------------------------------
|
||||
|
||||
export const JSON_RPC_PARSE_ERROR = -32700;
|
||||
export const JSON_RPC_INTERNAL_ERROR = -32603;
|
||||
|
||||
// ---- Shared data types ------------------------------------------------------
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Emitter } from '../../../base/common/event.js';
|
||||
import { Disposable } from '../../../base/common/lifecycle.js';
|
||||
import { connectionTokenQueryName } from '../../../base/common/network.js';
|
||||
import { ILogService } from '../../log/common/log.js';
|
||||
import type { IProtocolMessage } from '../common/state/sessionProtocol.js';
|
||||
import { JSON_RPC_PARSE_ERROR, type IProtocolMessage } from '../common/state/sessionProtocol.js';
|
||||
import type { IProtocolServer, IProtocolTransport } from '../common/state/sessionTransport.js';
|
||||
import { protocolReplacer, protocolReviver } from '../common/state/jsonSerialization.js';
|
||||
|
||||
@@ -58,7 +58,7 @@ export class WebSocketProtocolTransport extends Disposable implements IProtocolT
|
||||
const message = JSON.parse(text, protocolReviver) as IProtocolMessage;
|
||||
this._onMessage.fire(message);
|
||||
} catch {
|
||||
// Malformed message — drop. No logger available at transport level.
|
||||
this.send({ jsonrpc: '2.0', id: null!, error: { code: JSON_RPC_PARSE_ERROR, message: 'Parse error' } });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import { protocolReplacer, protocolReviver } from '../../common/state/jsonSerial
|
||||
import {
|
||||
isJsonRpcNotification,
|
||||
isJsonRpcResponse,
|
||||
JSON_RPC_PARSE_ERROR,
|
||||
type IActionBroadcastParams,
|
||||
type IFetchTurnsResult,
|
||||
type IJsonRpcErrorResponse,
|
||||
@@ -140,6 +141,31 @@ class TestProtocolClient {
|
||||
return predicate ? this._notifications.filter(predicate) : [...this._notifications];
|
||||
}
|
||||
|
||||
/** Send a raw string over the WebSocket without JSON serialization. */
|
||||
sendRaw(data: string): void {
|
||||
this._ws.send(data);
|
||||
}
|
||||
|
||||
/** Wait for the next raw message from the server. */
|
||||
waitForRawMessage(timeoutMs = 5000): Promise<unknown> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const timer = setTimeout(() => {
|
||||
cleanup();
|
||||
reject(new Error(`Timeout waiting for raw message (${timeoutMs}ms)`));
|
||||
}, timeoutMs);
|
||||
const onMsg = (data: Buffer | string) => {
|
||||
cleanup();
|
||||
const text = typeof data === 'string' ? data : data.toString('utf-8');
|
||||
resolve(JSON.parse(text));
|
||||
};
|
||||
const cleanup = () => {
|
||||
clearTimeout(timer);
|
||||
this._ws.removeListener('message', onMsg);
|
||||
};
|
||||
this._ws.on('message', onMsg);
|
||||
});
|
||||
}
|
||||
|
||||
close(): void {
|
||||
for (const w of this._notifWaiters) {
|
||||
w.reject(new Error('Client closed'));
|
||||
@@ -636,4 +662,21 @@ suite('Protocol WebSocket E2E', function () {
|
||||
const state = snapshot.state as ISessionState;
|
||||
assert.strictEqual(state.summary.model, 'new-mock-model');
|
||||
});
|
||||
|
||||
test('malformed JSON message returns parse error', async function () {
|
||||
this.timeout(10_000);
|
||||
|
||||
const raw = new TestProtocolClient(server.port);
|
||||
await raw.connect();
|
||||
|
||||
const responsePromise = raw.waitForRawMessage();
|
||||
raw.sendRaw('this is not valid json{{{');
|
||||
|
||||
const response = await responsePromise as IJsonRpcErrorResponse;
|
||||
assert.strictEqual(response.jsonrpc, '2.0');
|
||||
assert.strictEqual(response.id, null);
|
||||
assert.strictEqual(response.error.code, JSON_RPC_PARSE_ERROR);
|
||||
|
||||
raw.close();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user