Skip to content

Commit fed1f27

Browse files
committed
feat: handle method errors
1 parent 83517b7 commit fed1f27

File tree

3 files changed

+105
-9
lines changed

3 files changed

+105
-9
lines changed

packages/expressjs/src/main/ts/index.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,13 @@ import {
1313
parseJsonRpcObject,
1414
IParsedObjectRequest,
1515
RequestObject,
16+
error,
17+
success,
18+
JsonRpcError,
1619
} from '@qiwi/json-rpc-common'
1720

21+
export * from '@qiwi/json-rpc-common'
22+
1823
export const enum JsonRpcDecoratorType {
1924
REQUEST = 'request',
2025
ID = 'id',
@@ -36,14 +41,36 @@ export function JsonRpcMiddleware(): ClassDecorator {
3641

3742
if (jsonRpc.type === 'request') {
3843
const {params, handler} = (this.constructor as any).resolveHandler(this, jsonRpc)
39-
const result = handler
40-
? handler.apply(this, params)
41-
: {}
44+
const {payload: {id, method}} = jsonRpc
45+
46+
if (!handler) {
47+
res.status(200).send(error(id, JsonRpcError.methodNotFound(method)))
48+
49+
return
50+
}
4251

43-
res.status(200).send(result)
52+
const result = (this.constructor as any).handleResult(handler.apply(this, params))
53+
const jsonRpcResponse = result instanceof JsonRpcError
54+
? error(id, result)
55+
: success(id, result)
56+
57+
res.status(200).send(jsonRpcResponse)
4458
}
4559

4660
}
61+
62+
static handleResult(result: any): any {
63+
if (result instanceof JsonRpcError) {
64+
return result
65+
}
66+
67+
if (result instanceof Error) {
68+
return new JsonRpcError(result.message || '', 0)
69+
}
70+
71+
return result
72+
}
73+
4774
static resolveHandler(instance: Extended, jsonRpc: IParsedObjectRequest): {handler: Function, params: any[]} | {[key: string]: any} {
4875

4976
const _method = jsonRpc.payload.method

packages/expressjs/src/test/ts/index.ts

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
JsonRpcMiddleware,
44
RpcId,
55
JsonRpcParams,
6+
JsonRpcError,
67
} from '../../main/ts'
78

89
import reqresnext from 'reqresnext'
@@ -34,6 +35,11 @@ describe('expressjs-json-rpc', () => {
3435
return {foo: 'quxr', id, a, b}
3536
}
3637

38+
@JsonRpcMethod('get-some-error')
39+
getSomeError() {
40+
return new JsonRpcError('Some error', -100000)
41+
}
42+
3743
}
3844

3945
const controller = new SomeJsonRpcController()
@@ -55,7 +61,11 @@ describe('expressjs-json-rpc', () => {
5561
mware(req, res)
5662

5763
expect(res.statusCode).toBe(200)
58-
expect(res.body).toBe(JSON.stringify({foo: 'quxr', id: '123', a: 'a', b: 2}))
64+
expect(res.body).toBe(JSON.stringify({
65+
jsonrpc: '2.0',
66+
id: '123',
67+
result: {foo: 'quxr', id: '123', a: 'a', b: 2},
68+
}))
5969
})
6070

6171
it('finds proper method', () => {
@@ -74,7 +84,58 @@ describe('expressjs-json-rpc', () => {
7484
mware(req, res)
7585

7686
expect(res.statusCode).toBe(200)
77-
expect(res.body).toBe(JSON.stringify({foo: 'bar', id: '123'}))
87+
expect(res.body).toBe(JSON.stringify({
88+
jsonrpc: '2.0',
89+
id: '123',
90+
result: {foo: 'bar', id: '123'},
91+
}))
92+
})
93+
94+
it('returns error if method does not exist', () => {
95+
const {req, res} = reqresnext({
96+
body: {
97+
jsonrpc: '2.0',
98+
method: 'foobar',
99+
id: '111',
100+
params: {},
101+
},
102+
})
103+
104+
mware(req, res)
105+
106+
expect(res.statusCode).toBe(200)
107+
expect(res.body).toBe(JSON.stringify({
108+
jsonrpc: '2.0',
109+
id: '111',
110+
error: {
111+
message: 'Method not found',
112+
code: -32601,
113+
data: 'foobar',
114+
},
115+
}))
116+
})
117+
118+
it('returns error if method returns JsonRpcError', () => {
119+
const {req, res} = reqresnext({
120+
body: {
121+
jsonrpc: '2.0',
122+
method: 'get-some-error',
123+
id: '111',
124+
params: {},
125+
},
126+
})
127+
128+
mware(req, res)
129+
130+
expect(res.statusCode).toBe(200)
131+
expect(res.body).toBe(JSON.stringify({
132+
jsonrpc: '2.0',
133+
id: '111',
134+
error: {
135+
message: 'Some error',
136+
code: -100000,
137+
},
138+
}))
78139
})
79140
})
80141
})

packages/nestjs/src/test/ts/decorators.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ describe('decorators', () => {
7575
},
7676
})
7777
.expect(HttpStatus.OK)
78-
.expect({foo: 'quxr', id: '123', a: 'a', b: 2})
78+
.expect({
79+
jsonrpc: '2.0',
80+
id: '123',
81+
result: {foo: 'quxr', id: '123', a: 'a', b: 2},
82+
})
7983
})
8084

8185
it('finds proper method', () => {
@@ -85,10 +89,14 @@ describe('decorators', () => {
8589
jsonrpc: '2.0',
8690
method: 'test1',
8791
id: '123',
88-
params: null
92+
params: {},
8993
})
9094
.expect(HttpStatus.OK)
91-
.expect({foo: 'bar', id: '123'})
95+
.expect({
96+
jsonrpc: '2.0',
97+
id: '123',
98+
result: {foo: 'bar', id: '123'},
99+
})
92100
})
93101
})
94102
})

0 commit comments

Comments
 (0)