diff --git a/src/Error.ts b/src/Error.ts index d8d3ae2..9ce0ce1 100644 --- a/src/Error.ts +++ b/src/Error.ts @@ -6,6 +6,8 @@ export class JSONRPCError extends Error { public message: string; public code: number; public data?: unknown; + // For transports that run over Fetch. + public response?: Response; constructor(message: string, code: number, data?: any) { super(message); this.message = message; diff --git a/src/transports/EventEmitterTransport.ts b/src/transports/EventEmitterTransport.ts index 9583581..e7679db 100644 --- a/src/transports/EventEmitterTransport.ts +++ b/src/transports/EventEmitterTransport.ts @@ -31,7 +31,9 @@ class EventEmitterTransport extends Transport { this.transportRequestManager.settlePendingRequest(notifications); return prom; } catch (e) { - const responseErr = new JSONRPCError(e.message, ERR_UNKNOWN, e); + const responseErr = e instanceof JSONRPCError + ? e + : new JSONRPCError(e.message, ERR_UNKNOWN, e); this.transportRequestManager.settlePendingRequest(notifications, responseErr); return Promise.reject(responseErr); } diff --git a/src/transports/HTTPTransport.ts b/src/transports/HTTPTransport.ts index 06b8f9c..df51db1 100644 --- a/src/transports/HTTPTransport.ts +++ b/src/transports/HTTPTransport.ts @@ -39,8 +39,9 @@ class HTTPTransport extends Transport { const notifications = getNotifications(data); const batch = getBatchRequests(data); const fetcher = this.injectedFetcher || fetch; + let result; try { - const result = await fetcher(this.uri, { + result = await fetcher(this.uri, { method: "POST", headers: this.headers, body: JSON.stringify(this.parseData(data)), @@ -54,13 +55,18 @@ class HTTPTransport extends Transport { const body = await result.text(); const responseErr = this.transportRequestManager.resolveResponse(body); if (responseErr) { - // requirements are that batch requuests are successfully resolved + // requirements are that batch requests are successfully resolved // this ensures that individual requests within the batch request are settled this.transportRequestManager.settlePendingRequest(batch, responseErr); return Promise.reject(responseErr); } } catch (e) { - const responseErr = new JSONRPCError(e.message, ERR_UNKNOWN, e); + const responseErr = e instanceof JSONRPCError + ? e + : new JSONRPCError(e.message, ERR_UNKNOWN, e); + responseErr.response = result + || (e?.response instanceof Response && e.response) + || undefined; this.transportRequestManager.settlePendingRequest( notifications, responseErr diff --git a/src/transports/TransportRequestManager.ts b/src/transports/TransportRequestManager.ts index 03d679f..a19b890 100644 --- a/src/transports/TransportRequestManager.ts +++ b/src/transports/TransportRequestManager.ts @@ -67,7 +67,9 @@ export class TransportRequestManager { } return this.resolveRes(data, emitError); } catch (e) { - const err = new JSONRPCError("Bad response format", ERR_UNKNOWN, payload); + const err = e instanceof JSONRPCError + ? e + : new JSONRPCError("Bad response format", ERR_UNKNOWN, payload); if (emitError) { this.transportEventChannel.emit("error", err); } @@ -122,17 +124,19 @@ export class TransportRequestManager { private resolveRes(data: IJSONRPCNotificationResponse | IJSONRPCResponse, emitError: boolean): TransportResponse { const { id, error } = data; - const status = this.pendingRequest[id as string]; - if (status) { - delete this.pendingRequest[id as string]; - this.processResult(data, status); - this.transportEventChannel.emit("response", data as IJSONRPCResponse); - return; - } if (id === undefined && error === undefined) { this.transportEventChannel.emit("notification", data as IJSONRPCNotificationResponse); return; } + const status = this.pendingRequest[id as string]; + if (status) { + delete this.pendingRequest[id as string]; + if (error === undefined) { + this.processResult(data, status); + this.transportEventChannel.emit("response", data as IJSONRPCResponse); + return; + } + } let err; if (error) { err = convertJSONToRPCError(data); diff --git a/src/transports/WebSocketTransport.ts b/src/transports/WebSocketTransport.ts index 5727ddd..bebe6a7 100644 --- a/src/transports/WebSocketTransport.ts +++ b/src/transports/WebSocketTransport.ts @@ -33,8 +33,9 @@ class WebSocketTransport extends Transport { this.connection.send(JSON.stringify(this.parseData(data))); this.transportRequestManager.settlePendingRequest(notifications); } catch (err) { - const jsonError = new JSONRPCError((err as any).message, ERR_UNKNOWN, err); - + const jsonError = err instanceof JSONRPCError + ? err + : new JSONRPCError(e.message, ERR_UNKNOWN, err); this.transportRequestManager.settlePendingRequest(notifications, jsonError); this.transportRequestManager.settlePendingRequest(getBatchRequests(data), jsonError);