Skip to content

Commit

Permalink
[IND-445] Add legal copy for websocket error messages for blocked add…
Browse files Browse the repository at this point in the history
…resses. (#622)
  • Loading branch information
vincentwschau authored Oct 13, 2023
1 parent c26cb16 commit a814748
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 3 deletions.
35 changes: 34 additions & 1 deletion indexer/services/socks/__tests__/lib/subscriptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
} from '@dydxprotocol-indexer/postgres';
import { btcTicker, invalidChannel, invalidTicker } from '../constants';
import { axiosRequest } from '../../src/lib/axios';
import { makeAxiosSafeServerError } from '@dydxprotocol-indexer/base';
import { AxiosSafeServerError, makeAxiosSafeServerError } from '@dydxprotocol-indexer/base';
import { BlockedError } from '../../src/lib/errors';

jest.mock('ws');
jest.mock('../../src/helpers/wss');
Expand Down Expand Up @@ -217,6 +218,38 @@ describe('Subscriptions', () => {
expect(subscriptions.subscriptionLists[connectionId]).toBeUndefined();
});

it('sends blocked error message if initial message request fails with 403', async () => {
const expectedError: BlockedError = new BlockedError();
axiosRequestMock.mockImplementation(
() => {
throw new AxiosSafeServerError({
data: {},
status: 403,
statusText: '',
}, {});
},
);
await subscriptions.subscribe(
mockWs,
Channel.V4_ACCOUNTS,
connectionId,
initialMsgId,
mockSubaccountId,
);

expect(sendMessageMock).toHaveBeenCalledTimes(1);
expect(sendMessageMock).toHaveBeenCalledWith(
mockWs,
connectionId,
expect.objectContaining({
connection_id: connectionId,
type: 'error',
message: expectedError.message,
}));
expect(subscriptions.subscriptions[Channel.V4_ACCOUNTS]).toBeUndefined();
expect(subscriptions.subscriptionLists[connectionId]).toBeUndefined();
});

it('sends empty contents if initial message request fails with 404 for accounts', async () => {
axiosRequestMock.mockImplementation(() => {
return Promise.reject(makeAxiosSafeServerError(404, '', ''));
Expand Down
9 changes: 9 additions & 0 deletions indexer/services/socks/src/lib/errors.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { INDEXER_COMPLIANCE_BLOCKED_PAYLOAD } from '@dydxprotocol-indexer/compliance';

export class InvalidForwardMessageError extends Error {
constructor(message: string) {
super(`Invalid forwarded message. Error: ${message}.`);
Expand All @@ -18,3 +20,10 @@ export class InvalidTopicError extends Error {
this.name = 'InvalidTopicError';
}
}

export class BlockedError extends Error {
constructor() {
super(INDEXER_COMPLIANCE_BLOCKED_PAYLOAD);
this.name = 'BlockedError';
}
}
16 changes: 14 additions & 2 deletions indexer/services/socks/src/lib/subscription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
} from '../types';
import { axiosRequest } from './axios';
import { V4_MARKETS_ID, WS_CLOSE_CODE_POLICY_VIOLATION } from './constants';
import { InvalidChannelError } from './errors';
import { BlockedError, InvalidChannelError } from './errors';
import { RateLimiter } from './rate-limit';

const COMLINK_URL: string = `http://${config.COMLINK_URL}`;
Expand Down Expand Up @@ -140,11 +140,18 @@ export class Subscriptions {
id,
});

// For blocked errors add the erorr message into the error message sent in the websocket
// connection
let errorMsg: string = `Internal error, could not fetch data for subscription: ${channel}.`;
if (error instanceof BlockedError) {
errorMsg = error.message;
}

sendMessage(
ws,
connectionId,
createErrorMessage(
`Internal error, could not fetch data for subscription: ${channel}`,
errorMsg,
connectionId,
messageId,
),
Expand Down Expand Up @@ -521,6 +528,11 @@ export class Subscriptions {
if (error instanceof AxiosSafeServerError && (error as AxiosSafeServerError).status === 404) {
return EMPTY_INITIAL_RESPONSE;
}
// 403 indicates a blocked address. Throw a specific error for blocked addresses with a
// specific error message detailing why the subscription failed due to a blocked address.
if (error instanceof AxiosSafeServerError && (error as AxiosSafeServerError).status === 403) {
throw new BlockedError();
}
throw error;
}
}
Expand Down

0 comments on commit a814748

Please sign in to comment.