Skip to content

Commit

Permalink
feat: better error logs (#262)
Browse files Browse the repository at this point in the history
* checkpoint

* go

* undo that change

* handle no data returned

* add ws

* go
  • Loading branch information
guibescos authored Nov 27, 2024
1 parent 123fe7d commit e6e3774
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 40 deletions.
11 changes: 0 additions & 11 deletions scripts/dex-router/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ const MINUTE_IN_SECS = 60;

export class DexRouter {
private client: Client;
private pingTimeout: NodeJS.Timeout | undefined;
private mintDecimals: Record<string, number> = {};
private baseLookupTableAddresses: PublicKey[] = [];
private lookupTableAccounts: Record<string, AddressLookupTableAccount> = {};
Expand All @@ -51,7 +50,6 @@ export class DexRouter {
private readonly routers: Router[];
private readonly executor: Keypair;
private readonly chainId: string;
private readonly PING_INTERVAL = 30000;

constructor(
endpoint: string,
Expand Down Expand Up @@ -367,15 +365,6 @@ export class DexRouter {
return accountsToReturn;
}

heartbeat() {
if (this.pingTimeout !== undefined) clearTimeout(this.pingTimeout);

this.pingTimeout = setTimeout(() => {
console.error("Received no ping. Terminating connection.");
this.client.websocket?.terminate();
}, this.PING_INTERVAL + 2000); // 2 seconds for latency
}

async start() {
try {
await this.client.subscribeChains([this.chainId]);
Expand Down
15 changes: 0 additions & 15 deletions scripts/swap-beacon/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@ export function getSwapAdapterConfig(chainId: string) {

export class SwapBeacon {
private client: Client;
private pingTimeout: NodeJS.Timeout | undefined;
private readonly adapters: Adapter[];
private readonly chainIds: string[];
private readonly PING_INTERVAL = 30000;

constructor(endpoint: string, _chainIds: string[]) {
this.client = new Client(
Expand Down Expand Up @@ -253,25 +251,12 @@ export class SwapBeacon {
);
}

heartbeat() {
if (this.pingTimeout !== undefined) clearTimeout(this.pingTimeout);

this.pingTimeout = setTimeout(() => {
console.error("Received no ping. Terminating connection.");
this.client.websocket.terminate();
}, this.PING_INTERVAL + 2000); // 2 seconds for latency
}

async start() {
try {
await this.client.subscribeChains(this.chainIds);
console.log(
`Subscribed to chain ${this.chainIds}. Waiting for opportunities...`
);
this.heartbeat();
this.client.websocket.on("ping", () => {
this.heartbeat();
});
} catch (error) {
console.error(error);
this.client.websocket?.close();
Expand Down
4 changes: 2 additions & 2 deletions sdk/js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sdk/js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pythnetwork/express-relay-js",
"version": "0.15.0",
"version": "0.15.1",
"description": "Utilities for interacting with the express relay protocol",
"homepage": "https://github.com/pyth-network/per/tree/main/sdk/js",
"author": "Douro Labs",
Expand Down
76 changes: 65 additions & 11 deletions sdk/js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,17 @@ import * as svm from "./svm";
export * from "./types";
export * from "./const";

export class ClientError extends Error {}
export class ClientError extends Error {
static newHttpError(error: string, status?: number) {
const message = `Auction server http error ${status ?? ""} - ${error}`;
return new ClientError(message);
}

static newWebsocketError(error: string) {
const message = `Auction server websocket error - ${error}`;
return new ClientError(message);
}
}

type ClientOptions = FetchClientOptions & {
baseUrl: string;
Expand All @@ -48,10 +58,15 @@ export interface WsOptions {
* Max time to wait for a response from the server in milliseconds
*/
response_timeout: number;
/**
* Heartbeat interval at which the server is expected to send a ping
*/
ping_interval: number;
}

const DEFAULT_WS_OPTIONS: WsOptions = {
response_timeout: 10000,
ping_interval: 32000, // 30 seconds + 2 seconds to account for extra latency
};

export function checkHex(hex: string): Hex {
Expand Down Expand Up @@ -87,6 +102,7 @@ export class Client {
string,
(response: components["schemas"]["ServerResultMessage"]) => void
> = {};
private pingTimeout: NodeJS.Timeout | undefined;
private websocketOpportunityCallback?: (
opportunity: Opportunity
) => Promise<void>;
Expand Down Expand Up @@ -127,6 +143,7 @@ export class Client {
...this.getAuthorization(),
};
this.wsOptions = { ...DEFAULT_WS_OPTIONS, ...wsOptions };
this.pingTimeout = undefined;
this.websocketOpportunityCallback = opportunityCallback;
this.websocketBidStatusCallback = bidStatusCallback;
this.websocketSvmChainUpdateCallback = svmChainUpdateCallback;
Expand Down Expand Up @@ -209,6 +226,23 @@ export class Client {
console.error(message.error);
}
});
this.websocket.on("error", (error) => {
console.error(ClientError.newWebsocketError(error.message));
});
this.websocket.on("ping", () => {
if (this.pingTimeout !== undefined) {
clearTimeout(this.pingTimeout);
}

this.pingTimeout = setTimeout(() => {
console.error(
ClientError.newWebsocketError(
"Received no ping. Terminating connection."
)
);
this.websocket?.terminate();
}, this.wsOptions.ping_interval);
});
}

/**
Expand Down Expand Up @@ -257,7 +291,7 @@ export class Client {
if (response.status === "success") {
resolve(response.result);
} else {
reject(response.result);
reject(ClientError.newWebsocketError(response.result));
}
};
if (this.websocket === undefined) {
Expand All @@ -271,12 +305,16 @@ export class Client {
} else if (this.websocket.readyState === WebSocket.OPEN) {
this.websocket.send(JSON.stringify(msg_with_id));
} else {
reject("Websocket connection closing or already closed");
reject(
ClientError.newWebsocketError(
"Websocket connection closing or already closed"
)
);
}
}
setTimeout(() => {
delete this.callbackRouter[msg_with_id.id];
reject("Websocket response timeout");
reject(ClientError.newWebsocketError("Websocket response timeout"));
}, this.wsOptions.response_timeout);
});
}
Expand Down Expand Up @@ -380,7 +418,10 @@ export class Client {
body: body,
});
if (response.error) {
throw new ClientError(response.error.error);
throw ClientError.newHttpError(
response.error.error,
response.response.status
);
}
}

Expand Down Expand Up @@ -410,7 +451,10 @@ export class Client {
body,
});
if (response.error) {
throw new ClientError(response.error.error);
throw ClientError.newHttpError(
response.error.error,
response.response.status
);
}
}

Expand All @@ -429,19 +473,26 @@ export class Client {
bid: serverBid,
},
});

if (result === null) {
throw new ClientError("Empty response in websocket for bid submission");
throw ClientError.newWebsocketError(
"Empty response in websocket for bid submission"
);
}

return result.id;
} else {
const client = createClient<paths>(this.clientOptions);
const response = await client.POST("/v1/bids", {
body: serverBid,
});
if (response.error) {
throw new ClientError(response.error.error);
throw ClientError.newHttpError(
response.error.error,
response.response.status
);
} else if (response.data === undefined) {
throw new ClientError("No data returned");
throw ClientError.newHttpError("No data returned");
} else {
return response.data.id;
}
Expand All @@ -459,9 +510,12 @@ export class Client {
params: { query: { from_time: fromTime?.toISOString() } },
});
if (response.error) {
throw new ClientError(response.error.error);
throw ClientError.newHttpError(
response.error.error,
response.response.status
);
} else if (response.data === undefined) {
throw new ClientError("No data returned");
throw ClientError.newHttpError("No data returned");
} else {
return response.data;
}
Expand Down

0 comments on commit e6e3774

Please sign in to comment.