Skip to content

Commit

Permalink
feat: Add hook for custom Error data close #8
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack-Works committed Jun 26, 2020
1 parent 0154f23 commit 2ab36bb
Show file tree
Hide file tree
Showing 14 changed files with 226 additions and 146 deletions.
75 changes: 2 additions & 73 deletions __tests__/__snapshots__/jsonrpc.ts.snap
Expand Up @@ -4,10 +4,6 @@ exports[`ErrorResponse 1`] = `
Object {
"error": Object {
"code": 0,
"data": Object {
"stack": "",
"type": "Error",
},
"message": "",
},
"id": null,
Expand All @@ -19,10 +15,6 @@ exports[`ErrorResponse 2`] = `
Object {
"error": Object {
"code": -0,
"data": Object {
"stack": "",
"type": "Error",
},
"message": "",
},
"id": "",
Expand All @@ -34,85 +26,28 @@ exports[`ErrorResponse 3`] = `
Object {
"error": Object {
"code": -1,
"data": Object {
"stack": "",
"type": "Error",
},
"message": "",
},
"id": "",
"jsonrpc": "2.0",
}
`;

exports[`ErrorResponse: internal error 1`] = `
Object {
"error": Object {
"code": -32603,
"data": Object {
"stack": "",
"type": "Error",
},
"message": "Internal errormsg",
},
"id": "id",
"jsonrpc": "2.0",
}
`;

exports[`ErrorResponse: invalid code 1`] = `
Object {
"error": Object {
"code": -124,
"data": Object {
"stack": "stack",
"type": "Object",
},
"message": "message",
},
"id": "id2",
"jsonrpc": "2.0",
}
`;

exports[`ErrorResponse: invalid error object 1`] = `
Object {
"error": Object {
"code": 123,
"data": Object {
"stack": "stack",
"type": "Error",
},
"message": "",
},
"id": "id",
"jsonrpc": "2.0",
}
`;

exports[`ErrorResponse: invalid params 1`] = `
Object {
"error": Object {
"code": -32602,
"data": Object {
"stack": "",
"type": "Error",
},
"message": "Invalid params",
},
"id": "id",
"jsonrpc": "2.0",
}
`;

exports[`ErrorResponse: invalid req 1`] = `
Object {
"error": Object {
"code": -32600,
"data": Object {
"stack": "",
"type": "Error",
},
"message": "Invalid Request",
},
"id": "id",
Expand All @@ -124,10 +59,6 @@ exports[`ErrorResponse: method not found 1`] = `
Object {
"error": Object {
"code": -32601,
"data": Object {
"stack": "",
"type": "Error",
},
"message": "Method not found",
},
"id": "id",
Expand All @@ -140,8 +71,7 @@ Object {
"error": Object {
"code": -123,
"data": Object {
"stack": "stack",
"type": "Error",
"_data_": 1,
},
"message": "message",
},
Expand All @@ -155,8 +85,7 @@ Object {
"error": Object {
"code": -32700,
"data": Object {
"stack": "stack",
"type": "Error",
"my_data": true,
},
"message": "Parse error",
},
Expand Down
10 changes: 4 additions & 6 deletions __tests__/__snapshots__/raw-messages.ts.snap
Expand Up @@ -22,17 +22,15 @@ Array [

exports[`Bad messages: in 1`] = `
Array [
"{\\"error\\":{\\"code\\":-32700,\\"message\\":\\"Parse error\\",\\"data\\":{\\"stack\\":\\"<mocked stack>\\",\\"type\\":\\"Error\\"}},\\"id\\":null,\\"jsonrpc\\":\\"2.0\\"}",
"{\\"error\\":{\\"code\\":-32600,\\"message\\":\\"Invalid Request\\",\\"data\\":{\\"stack\\":\\"\\",\\"type\\":\\"Error\\"}},\\"id\\":\\"id0\\",\\"jsonrpc\\":\\"2.0\\"}",
"{\\"error\\":{\\"code\\":-32600,\\"message\\":\\"Invalid Request\\",\\"data\\":{\\"stack\\":\\"\\",\\"type\\":\\"Error\\"}},\\"id\\":null,\\"jsonrpc\\":\\"2.0\\"}",
"{\\"error\\":{\\"code\\":-32600,\\"message\\":\\"Invalid Request\\",\\"data\\":{\\"stack\\":\\"\\",\\"type\\":\\"Error\\"}},\\"id\\":\\"id1\\",\\"jsonrpc\\":\\"2.0\\"}",
"{\\"error\\":{\\"code\\":-32700,\\"message\\":\\"Parse error\\",\\"data\\":{\\"stack\\":\\"<mocked stack>\\",\\"type\\":\\"SyntaxError\\"}},\\"id\\":null,\\"jsonrpc\\":\\"2.0\\"}",
"{\\"error\\":{\\"code\\":-32600,\\"message\\":\\"Invalid Request\\"},\\"id\\":\\"id0\\",\\"jsonrpc\\":\\"2.0\\"}",
"{\\"error\\":{\\"code\\":-32600,\\"message\\":\\"Invalid Request\\"},\\"id\\":null,\\"jsonrpc\\":\\"2.0\\"}",
]
`;

exports[`Bad messages: in 2`] = `
Array [
"{\\"error\\":{\\"code\\":-32700,\\"message\\":\\"Parse error\\",\\"data\\":{\\"stack\\":\\"<mocked stack>\\",\\"type\\":\\"Error\\"}},\\"id\\":null,\\"jsonrpc\\":\\"2.0\\"}",
"{\\"error\\":{\\"code\\":-32600,\\"message\\":\\"Invalid Request\\",\\"data\\":{\\"stack\\":\\"\\",\\"type\\":\\"Error\\"}},\\"id\\":\\"id1\\",\\"jsonrpc\\":\\"2.0\\"}",
"{\\"error\\":{\\"code\\":-32700,\\"message\\":\\"Parse error\\",\\"data\\":{\\"stack\\":\\"<mocked stack>\\",\\"type\\":\\"SyntaxError\\"}},\\"id\\":null,\\"jsonrpc\\":\\"2.0\\"}",
]
`;

Expand Down
7 changes: 3 additions & 4 deletions __tests__/__snapshots__/web.ts.snap
Expand Up @@ -5,14 +5,13 @@ exports[`DOMException 1`] = `[MyError: Message]`;
exports[`DOMException 2`] = `
Object {
"error": Object {
"code": 0,
"code": -1,
"data": Object {
"stack": "stack",
"type": "DOMException:name",
},
"message": "msg",
"message": "msg2",
},
"id": "id",
"id": 1,
"jsonrpc": "2.0",
}
`;
33 changes: 21 additions & 12 deletions __tests__/jsonrpc.ts
@@ -1,4 +1,12 @@
import { Request, SuccessResponse, ErrorResponse, hasKey, isJSONRPCObject, isObject } from '../src/utils/jsonrpc'
import {
Request,
SuccessResponse,
ErrorResponse,
hasKey,
isJSONRPCObject,
isObject,
ErrorResponseMapped,
} from '../src/utils/jsonrpc'
test('Request', () => {
expect(Request('id', 'method', ['param1', 'param2'], 'stack')).toMatchSnapshot('req1')
expect(Request('id2', 'method', { param1: 'abc', param2: 'def' }, 'stack')).toMatchSnapshot('req2')
Expand All @@ -10,19 +18,20 @@ test('SuccessResponse', () => {
})

test('ErrorResponse', () => {
const err = new Error()
err.stack = 'stack'
expect(ErrorResponse('id2', -123, 'message', 'stack', err)).toMatchSnapshot('normal error')
expect(ErrorResponse('id', 123, 'message', 'stack', '')).toMatchSnapshot('invalid error object')
expect(ErrorResponse('id2', -123.456, 'message', 'stack', { stack: 'item' })).toMatchSnapshot('invalid code')
expect(ErrorResponse(undefined, 0, '', '')).toMatchSnapshot()
expect(ErrorResponse('', -0, '', '')).toMatchSnapshot()
expect(ErrorResponse('', NaN, '', '')).toMatchSnapshot()
expect(ErrorResponse.InternalError('id', 'msg')).toMatchSnapshot('internal error')
expect(ErrorResponse.InvalidParams('id')).toMatchSnapshot('invalid params')
expect(ErrorResponse('id2', -123, 'message', { _data_: 1 })).toMatchSnapshot('normal error')
expect(ErrorResponse('id2', -123.456, 'message')).toMatchSnapshot('invalid code')
expect(ErrorResponse(undefined, 0, '')).toMatchSnapshot()
expect(ErrorResponse('', -0, '')).toMatchSnapshot()
expect(ErrorResponse('', NaN, '')).toMatchSnapshot()
expect(ErrorResponse.InvalidRequest('id')).toMatchSnapshot('invalid req')
expect(ErrorResponse.MethodNotFound('id')).toMatchSnapshot('method not found')
expect(ErrorResponse.ParseError('stack')).toMatchSnapshot('parse error')
expect(
ErrorResponseMapped.ParseError(new Error(), () => ({
code: 2345,
message: 'My message',
data: { my_data: true },
})),
).toMatchSnapshot('parse error')
})

test('hasKey', () => {
Expand Down
8 changes: 5 additions & 3 deletions __tests__/web.ts
Expand Up @@ -4,22 +4,24 @@ class Exception extends Error {
}
}
test('DOMException', async () => {
const { ErrorResponse } = await import('../src/utils/jsonrpc')
const { defaultErrorMapper, ErrorResponseMapped, Request } = await import('../src/utils/jsonrpc')
const { DOMException, DOMExceptionHeader, RecoverError } = await import('../src/utils/error')
expect(DOMException).not.toBeUndefined()
const e = RecoverError(DOMExceptionHeader + 'MyError', 'Message', 0, '')
expect(e).toMatchSnapshot()
expect(e).toBeInstanceOf(Exception)

expect(ErrorResponse('id', 0, 'msg', 'stack', new Exception('msg2', 'name'))).toMatchSnapshot()
expect(
ErrorResponseMapped(Request(1, 'x', [], ''), new Exception('msg2', 'name'), defaultErrorMapper()),
).toMatchSnapshot()
})

test('preservePauseOnException', async () => {
const { preservePauseOnException } = await import('../src/utils/preservePauseOnException')
const { createServer } = await import('./shared')

const e = () => {}
await expect(preservePauseOnException(e, async () => 1, [])).resolves.toBe(1)
await expect(preservePauseOnException(e, async () => 1, undefined, [])).resolves.toBe(1)
// const throws = async () => {
// // Jest cannot let us test unhandledRejection well https://github.com/facebook/jest/issues/5620
// throw new Error('unhandledRejection test')
Expand Down
13 changes: 13 additions & 0 deletions docs/async-call-rpc.asynccalloptions.maperror.md
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [async-call-rpc](./async-call-rpc.md) &gt; [AsyncCallOptions](./async-call-rpc.asynccalloptions.md) &gt; [mapError](./async-call-rpc.asynccalloptions.maperror.md)

## AsyncCallOptions.mapError property

Control the error response data

<b>Signature:</b>

```typescript
mapError?: ErrorMapFunction<unknown>;
```
1 change: 1 addition & 0 deletions docs/async-call-rpc.asynccalloptions.md
Expand Up @@ -19,6 +19,7 @@ export interface AsyncCallOptions
| [key](./async-call-rpc.asynccalloptions.key.md) | string | A key to prevent collision with other AsyncCalls. |
| [log](./async-call-rpc.asynccalloptions.log.md) | [AsyncCallLogLevel](./async-call-rpc.asynccallloglevel.md) \| boolean | Choose log level. See [AsyncCallLogLevel](./async-call-rpc.asynccallloglevel.md) |
| [logger](./async-call-rpc.asynccalloptions.logger.md) | [Console](./async-call-rpc.console.md) | The logger of AsyncCall |
| [mapError](./async-call-rpc.asynccalloptions.maperror.md) | [ErrorMapFunction](./async-call-rpc.errormapfunction.md)<!-- -->&lt;unknown&gt; | Control the error response data |
| [messageChannel](./async-call-rpc.asynccalloptions.messagechannel.md) | [MessageChannel](./async-call-rpc.messagechannel.md) | The message channel can let you transport messages between server and client |
| [parameterStructures](./async-call-rpc.asynccalloptions.parameterstructures.md) | 'by-position' \| 'by-name' | How parameters passed to remote |
| [preferLocalImplementation](./async-call-rpc.asynccalloptions.preferlocalimplementation.md) | boolean | Prefer local implementation than remote. |
Expand Down
2 changes: 1 addition & 1 deletion docs/async-call-rpc.asynccallstrictjsonrpc.md
Expand Up @@ -16,6 +16,6 @@ export interface AsyncCallStrictJSONRPC

| Property | Type | Description |
| --- | --- | --- |
| [methodNotFound](./async-call-rpc.asynccallstrictjsonrpc.methodnotfound.md) | boolean | Return an error when the requested method is not defined |
| [methodNotFound](./async-call-rpc.asynccallstrictjsonrpc.methodnotfound.md) | boolean | Return an error when the requested method is not defined, otherwise, ignore the request. |
| [unknownMessage](./async-call-rpc.asynccallstrictjsonrpc.unknownmessage.md) | boolean | send an error when receive invalid JSON RPC payload |

Expand Up @@ -4,7 +4,7 @@

## AsyncCallStrictJSONRPC.methodNotFound property

Return an error when the requested method is not defined
Return an error when the requested method is not defined, otherwise, ignore the request.

<b>Signature:</b>

Expand Down
21 changes: 21 additions & 0 deletions docs/async-call-rpc.errormapfunction.md
@@ -0,0 +1,21 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [async-call-rpc](./async-call-rpc.md) &gt; [ErrorMapFunction](./async-call-rpc.errormapfunction.md)

## ErrorMapFunction type


<b>Signature:</b>

```typescript
export declare type ErrorMapFunction<T = unknown> = (error: unknown, request: Readonly<{
jsonrpc: '2.0';
id?: string | number | null;
method: string;
params: readonly unknown[] | object;
}>) => {
code: number;
message: string;
data?: T;
};
```
6 changes: 6 additions & 0 deletions docs/async-call-rpc.md
Expand Up @@ -35,3 +35,9 @@ See the introduction at [Github](https://github.com/Jack-Works/async-call)
| [JSONSerialization](./async-call-rpc.jsonserialization.md) | Create a serialization by JSON.parse/stringify |
| [NoSerialization](./async-call-rpc.noserialization.md) | Serialization implementation that do nothing |

## Type Aliases

| Type Alias | Description |
| --- | --- |
| [ErrorMapFunction](./async-call-rpc.errormapfunction.md) | |

13 changes: 13 additions & 0 deletions etc/async-call-rpc.api.md
Expand Up @@ -24,6 +24,7 @@ export interface AsyncCallOptions {
key?: string;
log?: AsyncCallLogLevel | boolean;
logger?: Console;
mapError?: ErrorMapFunction<unknown>;
messageChannel: MessageChannel;
parameterStructures?: 'by-position' | 'by-name';
preferLocalImplementation?: boolean;
Expand Down Expand Up @@ -69,6 +70,18 @@ export interface Console {
log(...args: unknown[]): void;
}

// @public (undocumented)
export type ErrorMapFunction<T = unknown> = (error: unknown, request: Readonly<{
jsonrpc: '2.0';
id?: string | number | null;
method: string;
params: readonly unknown[] | object;
}>) => {
code: number;
message: string;
data?: T;
};

// @public
export const JSONSerialization: (replacerAndReceiver?: [(((key: string, value: any) => any) | undefined)?, (((key: string, value: any) => any) | undefined)?], space?: string | number | undefined, undefinedKeepingBehavior?: 'keep' | 'null' | false) => Serialization;

Expand Down

0 comments on commit 2ab36bb

Please sign in to comment.