diff --git a/package.json b/package.json index 490b055..2936c50 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@orionprotocol/sdk", - "version": "0.17.34", + "version": "0.17.35", "description": "Orion Protocol SDK", "main": "./lib/esm/index.js", "module": "./lib/esm/index.js", diff --git a/src/__tests__/orionAggregator.test.ts b/src/__tests__/orionAggregator.test.ts new file mode 100644 index 0000000..9384d49 --- /dev/null +++ b/src/__tests__/orionAggregator.test.ts @@ -0,0 +1,30 @@ +import Orion from '../Orion'; + +describe('Orion Aggregator', () => { + test('Handle error', async () => { + const orion = new Orion('testing'); + const bscUnit = orion.getUnit('bsc') + + let subId: string; + + await new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + bscUnit.orionAggregator.ws.unsubscribe(subId); + bscUnit.orionAggregator.ws.destroy() + reject(new Error('Timeout')); + }, 10000); + // bscUnit.orionAggregator.ws.onError = console.error; + const payload = 'adsv-sdfb'; + subId = bscUnit.orionAggregator.ws.subscribe('aus', { + payload, + callback: () => null, + errorCb: (message) => { + expect(message).toContain(`Address '${payload}' is not hexadecimal`); + clearTimeout(timeout); + bscUnit.orionAggregator.ws.destroy() + resolve(true); + } + }) + }); + }); +}); diff --git a/src/services/OrionAggregator/ws/index.ts b/src/services/OrionAggregator/ws/index.ts index d927fe1..ad56f2b 100644 --- a/src/services/OrionAggregator/ws/index.ts +++ b/src/services/OrionAggregator/ws/index.ts @@ -18,6 +18,7 @@ import assetPairConfigSchema from './schemas/assetPairConfigSchema'; import type { fullOrderSchema, orderUpdateSchema } from './schemas/addressUpdateSchema'; import cfdAddressUpdateSchema from './schemas/cfdAddressUpdateSchema'; import futuresTradeInfoSchema from './schemas/futuresTradeInfoSchema'; +import { objectKeys } from '../../../utils/objectKeys'; // import errorSchema from './schemas/errorSchema'; const UNSUBSCRIBE = 'u'; @@ -59,6 +60,7 @@ type AggregatedOrderbookSubscription = { bids: OrderbookItem[], pair: string ) => void + errorCb?: (message: string) => void } type SwapInfoSubscription = { @@ -74,6 +76,7 @@ type FuturesTradeInfoSubscription = { p?: number } callback: (futuresTradeInfo: FuturesTradeInfo) => void + errorCb?: (message: string) => void } type AddressUpdateUpdate = { @@ -113,6 +116,7 @@ type CfdAddressUpdateInitial = { type AddressUpdateSubscription = { payload: string callback: (data: AddressUpdateUpdate | AddressUpdateInitial) => void + errorCb?: (message: string) => void } type CfdAddressUpdateSubscription = { @@ -362,8 +366,19 @@ class OrionAggregatorWS { switch (json.T) { case MessageType.ERROR: { - const { m: errorMessage } = errorSchema.parse(json); - this.onError?.(errorMessage); + const err = errorSchema.parse(json); + // Get subscription error callback + // 2. Find subscription by id + // 3. Call onError callback + + const subType = objectKeys(this.subscriptions).find((st) => this.subscriptions[st]?.[err.id]); + if (subType === undefined) throw new Error('OrionAggregatorWS: cannot find subscription type by id'); + const sub = this.subscriptions[subType]?.[err.id]; + if (sub === undefined) throw new Error('OrionAggregatorWS: cannot find subscription by id'); + if ('errorCb' in sub) { + sub.errorCb(err.m); + } + this.onError?.(err.m); } break; case MessageType.PING_PONG: diff --git a/src/services/OrionAggregator/ws/schemas/errorSchema.ts b/src/services/OrionAggregator/ws/schemas/errorSchema.ts index 95a093d..a9ec03b 100644 --- a/src/services/OrionAggregator/ws/schemas/errorSchema.ts +++ b/src/services/OrionAggregator/ws/schemas/errorSchema.ts @@ -4,7 +4,8 @@ import baseMessageSchema from './baseMessageSchema'; const errorSchema = baseMessageSchema.extend({ T: z.literal(MessageType.ERROR), - c: z.number(), // code + c: z.number().int(), // code + id: z.string(), // subscription id m: z.string(), // error message, });