Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quick and dirty addition of stacktraces to errors #5

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 34 additions & 6 deletions typescript/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import WebSocket from 'isomorphic-ws'
import type { MessageEvent } from 'ws'
import { Request, Response, Message, Error, Params } from './jsonrpc'
import { Request, Response, Message, Error as jsonrpc_Error, Params, I32 } from './jsonrpc'

interface Transport {
request: (method: string, params?: Params) => Promise<unknown>,
Expand All @@ -9,7 +9,7 @@ interface Transport {

type RequestMap = Map<
number,
{ resolve: (result: unknown) => void; reject: (error: Error) => void }
{ resolve: (result: unknown) => void; reject: (error: jsonrpc_Error) => void, error_stack: string|undefined }
>;

type Options = {
Expand All @@ -18,9 +18,34 @@ type Options = {
maxReconnectInterval: number;
};

class ClientError extends Error {
code: I32
data: jsonrpc_Error["data"]
constructor(error: jsonrpc_Error){
super(error.message)
this.code = error.code
this.data = error.data
}
}

// type RequestEvent = MessageEvent<Request>;

abstract class ClientHandler extends EventTarget implements Transport {
function getStack() {
// better way would be to use error-stack-parser for this
const stack = new Error().stack
if(!stack) {
return undefined
}
if (stack.startsWith("Error\n")) {
const frames = stack.split("\n");
return ["[[ERROR]]", ...frames.slice(5)].join('\n');
}
else {
return stack.split("\n").slice(3).join('\n');
}
}

export abstract class ClientHandler extends EventTarget implements Transport {
private _requests: RequestMap = new Map();
private _requestId = 0;
_send(_message: Message): void {
Expand All @@ -39,8 +64,11 @@ abstract class ClientHandler extends EventTarget implements Transport {
if (!response.id) return; // TODO: Handle error.
const handler = this._requests.get(response.id);
if (!handler) return; // TODO: Handle error.
if (response.error) handler.reject(response.error);
else handler.resolve(response.result);
if (response.error) {
const error = new ClientError(response.error)
error.stack = handler.error_stack?.replace("[[ERROR]]", `Error: ${error.message}`)
handler.reject(error)
} else handler.resolve(response.result);
}

notification(method: string, params?: Params): void {
Expand All @@ -64,7 +92,7 @@ abstract class ClientHandler extends EventTarget implements Transport {
};
this._send(request as Message);
return new Promise((resolve, reject) => {
this._requests.set(id, { resolve, reject });
this._requests.set(id, { resolve, reject, error_stack: getStack() });
});
}
}
Expand Down