Skip to content

Commit 347afd8

Browse files
authored
Merge pull request #8 from pfrazee/master
Add CustomError responses
2 parents ae21dc6 + 6496cc6 commit 347afd8

File tree

5 files changed

+65
-0
lines changed

5 files changed

+65
-0
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,26 @@ for await (const req of server) {
3333
}
3434
```
3535

36+
#### custom errors
37+
38+
Throw a `CustomError` to send a server-defined error response.
39+
40+
```typescript
41+
import { CustomError, respond } from "https://deno.land/x/gentle_rpc/mod.ts";
42+
43+
//..
44+
await respond({
45+
throwError: () => {
46+
throw new CustomError(
47+
-32000, // the JSON-RPC error code. Note, must be -32000 to -32099
48+
"An error occurred", // the error message, a short sentence
49+
{ details: "..." }, // optional additional details, can be an object, primitive, etc (any)
50+
);
51+
},
52+
}, req);
53+
//..
54+
```
55+
3656
## Client
3757

3858
#### createRemote

mod.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ export { createRemote } from "./client/remote.ts";
22

33
export { respond } from "./server/response.ts";
44

5+
export { CustomError } from "./server/custom_error.ts";
6+
57
export { createRpcResponseObject } from "./server/creation.ts";
68

79
export type {

server/creation.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
} from "../json_rpc_types.ts";
77
import type { ValidationObject } from "./validation.ts";
88
import type { RespondOptions, ServerMethods } from "./response.ts";
9+
import { CustomError } from "./custom_error.ts";
910

1011
export type CreationInput = {
1112
validationObject: ValidationObject;
@@ -27,6 +28,15 @@ async function executeMethods(
2728
result: await methods[obj.method](obj.params),
2829
};
2930
} catch (err) {
31+
if (err instanceof CustomError) {
32+
return {
33+
code: err.code,
34+
message: err.message,
35+
id: obj.id,
36+
data: err.data,
37+
isError: true,
38+
};
39+
}
3040
return {
3141
code: -32603,
3242
message: "Internal error",

server/custom_error.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export class CustomError extends Error {
2+
name: string;
3+
code: number;
4+
data: any;
5+
6+
constructor(code: number, message: string, data?: any) {
7+
super(message);
8+
this.name = this.constructor.name;
9+
this.code = code;
10+
this.data = data;
11+
}
12+
}

tests/respond_test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88

99
import { respond } from "../server/response.ts";
1010

11+
import { CustomError } from "../server/custom_error.ts";
12+
1113
import type { ServerRequest } from "./test_deps.ts";
1214

1315
function createReq(str: string) {
@@ -34,6 +36,11 @@ const methods = {
3436
throwError: () => {
3537
throw new Error("my error");
3638
},
39+
throwCustomError: () => {
40+
throw new CustomError(-32000, "my custom error", {
41+
"details": "error details",
42+
});
43+
},
3744
};
3845

3946
Deno.test("rpc call with positional parameters", async function (): Promise<
@@ -233,3 +240,17 @@ Deno.test("set publicErrorStack to true", async function (): Promise<void> {
233240
"string",
234241
);
235242
});
243+
244+
Deno.test("rpc call with a custom error", async function (): Promise<
245+
void
246+
> {
247+
const sentToServer =
248+
'{"jsonrpc": "2.0", "method": "throwCustomError", "params": [], "id": 1}';
249+
const sentToClient =
250+
'{"jsonrpc":"2.0","error":{"code":-32000,"message":"my custom error","data":{"details":"error details"}},"id":1}';
251+
252+
assertEquals(
253+
await respond(methods, createReq(sentToServer)),
254+
removeWhiteSpace(sentToClient),
255+
);
256+
});

0 commit comments

Comments
 (0)