Skip to content

Commit 2fd4e35

Browse files
Merge pull request #103 from sumitesh9/sumiteshn9/fix-error-codes
Updates SDK error codes to use JSON-RPC server error range
2 parents 4658fd0 + ca31913 commit 2fd4e35

File tree

2 files changed

+68
-5
lines changed

2 files changed

+68
-5
lines changed

src/shared/protocol.test.ts

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { Protocol } from "./protocol.js";
2+
import { Transport } from "./transport.js";
3+
import {
4+
McpError,
5+
ErrorCode,
6+
Request,
7+
Result,
8+
Notification,
9+
} from "../types.js";
10+
import { ZodType, z } from "zod";
11+
12+
// Mock Transport class
13+
class MockTransport implements Transport {
14+
onclose?: () => void;
15+
onerror?: (error: Error) => void;
16+
onmessage?: (message: unknown) => void;
17+
18+
async start(): Promise<void> {}
19+
async close(): Promise<void> {
20+
this.onclose?.();
21+
}
22+
async send(_message: unknown): Promise<void> {}
23+
}
24+
25+
describe("protocol tests", () => {
26+
let protocol: Protocol<Request, Notification, Result>;
27+
let transport: MockTransport;
28+
29+
beforeEach(() => {
30+
transport = new MockTransport();
31+
protocol = new (class extends Protocol<Request, Notification, Result> {
32+
protected assertCapabilityForMethod(): void {}
33+
protected assertNotificationCapability(): void {}
34+
protected assertRequestHandlerCapability(): void {}
35+
})();
36+
});
37+
38+
test("should throw a timeout error if the request exceeds the timeout", async () => {
39+
await protocol.connect(transport);
40+
const request = { method: "example", params: {} };
41+
try {
42+
const mockSchema: ZodType<{ result: string }> = z.object({
43+
result: z.string(),
44+
});
45+
await protocol.request(request, mockSchema, {
46+
timeout: 0,
47+
});
48+
} catch (error) {
49+
expect(error).toBeInstanceOf(McpError);
50+
if (error instanceof McpError) {
51+
expect(error.code).toBe(ErrorCode.RequestTimeout);
52+
}
53+
}
54+
});
55+
56+
test("should invoke onclose when the connection is closed", async () => {
57+
const oncloseMock = jest.fn();
58+
protocol.onclose = oncloseMock;
59+
await protocol.connect(transport);
60+
await transport.close();
61+
expect(oncloseMock).toHaveBeenCalled();
62+
});
63+
});

src/types.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,13 @@ export const JSONRPCResponseSchema = z
100100
.strict();
101101

102102
/**
103-
* An incomplete set of error codes that may appear in JSON-RPC responses.
103+
* Error codes defined by the JSON-RPC specification.
104104
*/
105105
export enum ErrorCode {
106106
// SDK error codes
107-
ConnectionClosed = -1,
108-
RequestTimeout = -2,
109-
107+
ConnectionClosed = -32000,
108+
RequestTimeout = -32001,
109+
110110
// Standard JSON-RPC error codes
111111
ParseError = -32700,
112112
InvalidRequest = -32600,
@@ -1237,4 +1237,4 @@ export type ClientResult = z.infer<typeof ClientResultSchema>;
12371237
/* Server messages */
12381238
export type ServerRequest = z.infer<typeof ServerRequestSchema>;
12391239
export type ServerNotification = z.infer<typeof ServerNotificationSchema>;
1240-
export type ServerResult = z.infer<typeof ServerResultSchema>;
1240+
export type ServerResult = z.infer<typeof ServerResultSchema>;

0 commit comments

Comments
 (0)