Skip to content

Commit

Permalink
chore: add error to the subscription
Browse files Browse the repository at this point in the history
  • Loading branch information
petertonysmith94 committed Jan 13, 2025
1 parent 3758b1c commit 2914c67
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 42 deletions.
3 changes: 2 additions & 1 deletion packages/account/src/providers/fuel-graphql-subscriber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type FuelGraphQLSubscriberOptions = {
};

export class FuelGraphqlSubscriber implements AsyncIterator<unknown> {
public static incompatibleNodeVersionMessage: string | false = false;
private static textDecoder = new TextDecoder();

private constructor(private stream: ReadableStreamDefaultReader<Uint8Array>) {}
Expand Down Expand Up @@ -52,7 +53,7 @@ export class FuelGraphqlSubscriber implements AsyncIterator<unknown> {
if (this.events.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const { data, errors } = this.events.shift()!;
assertGqlResponseHasNoErrors(errors);
assertGqlResponseHasNoErrors(errors, FuelGraphqlSubscriber.incompatibleNodeVersionMessage);
return { value: data, done: false };
}
const { value, done } = await this.stream.read();
Expand Down
130 changes: 89 additions & 41 deletions packages/account/src/providers/provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { InputType, ReceiptType } from '@fuel-ts/transactions';
import { DateTime, arrayify, sleep } from '@fuel-ts/utils';
import { ASSET_A, ASSET_B } from '@fuel-ts/utils/test-utils';
import { versions } from '@fuel-ts/versions';
import * as fuelTsVersionsMod from '@fuel-ts/versions';

import { Wallet } from '..';
import {
Expand All @@ -21,6 +20,7 @@ import {
MOCK_TX_UNKNOWN_RAW_PAYLOAD,
MOCK_TX_SCRIPT_RAW_PAYLOAD,
} from '../../test/fixtures/transaction-summary';
import { mockIncompatibleVersions } from '../../test/utils/mockIncompabileVersions';
import { setupTestProviderAndWallets, launchNode, TestMessage } from '../test-utils';

import type { Coin } from './coin';
Expand Down Expand Up @@ -1137,24 +1137,11 @@ describe('Provider', () => {
expect(gasConfig.maxGasPerTx).toBeDefined();
});

it('warns on difference between major client version and supported major version', async () => {
const { FUEL_CORE } = versions;
const [major, minor, patch] = FUEL_CORE.split('.');
const majorMismatch = major === '0' ? 1 : parseInt(patch, 10) - 1;

const mock = {
isMajorSupported: false,
isMinorSupported: true,
isPatchSupported: true,
supportedVersion: `${majorMismatch}.${minor}.${patch}`,
};

if (mock.supportedVersion === FUEL_CORE) {
throw new Error();
}

const spy = vi.spyOn(fuelTsVersionsMod, 'checkFuelCoreVersionCompatibility');
spy.mockImplementationOnce(() => mock);
it('Prepend a warning to an error with version mismatch [major]', async () => {
const { current, supported } = mockIncompatibleVersions({
isMajorMismatch: true,
isMinorMismatch: false,
});

using launched = await setupTestProviderAndWallets();
const {
Expand All @@ -1170,31 +1157,18 @@ describe('Provider', () => {
message: [
`The account(s) sending the transaction don't have enough funds to cover the transaction.`,
``,
`The Fuel Node that you are trying to connect to is using fuel-core version ${FUEL_CORE}.`,
`The TS SDK currently supports fuel-core version ${mock.supportedVersion}.`,
`The Fuel Node that you are trying to connect to is using fuel-core version ${current.FUEL_CORE}.`,
`The TS SDK currently supports fuel-core version ${supported.FUEL_CORE}.`,
`Things may not work as expected.`,
].join('\n'),
});
});

it('warns on difference between minor client version and supported minor version', async () => {
const { FUEL_CORE } = versions;
const [major, minor, patch] = FUEL_CORE.split('.');
const minorMismatch = minor === '0' ? 1 : parseInt(patch, 10) - 1;

const mock = {
isMajorSupported: true,
isMinorSupported: false,
isPatchSupported: true,
supportedVersion: `${major}.${minorMismatch}.${patch}`,
};

if (mock.supportedVersion === FUEL_CORE) {
throw new Error();
}

const spy = vi.spyOn(fuelTsVersionsMod, 'checkFuelCoreVersionCompatibility');
spy.mockImplementationOnce(() => mock);
it('Prepend a warning to an error with version mismatch [minor]', async () => {
const { current, supported } = mockIncompatibleVersions({
isMajorMismatch: false,
isMinorMismatch: true,
});

using launched = await setupTestProviderAndWallets();
const {
Expand All @@ -1210,8 +1184,82 @@ describe('Provider', () => {
message: [
`The account(s) sending the transaction don't have enough funds to cover the transaction.`,
``,
`The Fuel Node that you are trying to connect to is using fuel-core version ${FUEL_CORE}.`,
`The TS SDK currently supports fuel-core version ${mock.supportedVersion}.`,
`The Fuel Node that you are trying to connect to is using fuel-core version ${current.FUEL_CORE}.`,
`The TS SDK currently supports fuel-core version ${supported.FUEL_CORE}.`,
`Things may not work as expected.`,
].join('\n'),
});
});

it('Prepend a warning to a subscription error with version mismatch [major]', async () => {
const { current, supported } = mockIncompatibleVersions({
isMajorMismatch: true,
isMinorMismatch: false,
});

using launched = await setupTestProviderAndWallets();
const { provider } = launched;

await expectToThrowFuelError(
async () => {
for await (const value of await provider.operations.statusChange({
transactionId: 'invalid transaction id',
})) {
// shouldn't be reached and should fail if reached
expect(value).toBeFalsy();
}
},

{ code: FuelError.CODES.INVALID_REQUEST }
);

const chainId = await provider.getChainId();
const response = new TransactionResponse('invalid transaction id', provider, chainId);

await expectToThrowFuelError(() => response.waitForResult(), {
code: FuelError.CODES.INVALID_REQUEST,
message: [
`Failed to parse "TransactionId": Invalid character 'i' at position 0`,
``,
`The Fuel Node that you are trying to connect to is using fuel-core version ${current.FUEL_CORE}.`,
`The TS SDK currently supports fuel-core version ${supported.FUEL_CORE}.`,
`Things may not work as expected.`,
].join('\n'),
});
});

it('Prepend a warning to a subscription error with version mismatch [minor]', async () => {
const { current, supported } = mockIncompatibleVersions({
isMajorMismatch: false,
isMinorMismatch: true,
});

using launched = await setupTestProviderAndWallets();
const { provider } = launched;

await expectToThrowFuelError(
async () => {
for await (const value of await provider.operations.statusChange({
transactionId: 'invalid transaction id',
})) {
// shouldn't be reached and should fail if reached
expect(value).toBeFalsy();
}
},

{ code: FuelError.CODES.INVALID_REQUEST }
);

const chainId = await provider.getChainId();
const response = new TransactionResponse('invalid transaction id', provider, chainId);

await expectToThrowFuelError(() => response.waitForResult(), {
code: FuelError.CODES.INVALID_REQUEST,
message: [
`Failed to parse "TransactionId": Invalid character 'i' at position 0`,
``,
`The Fuel Node that you are trying to connect to is using fuel-core version ${current.FUEL_CORE}.`,
`The TS SDK currently supports fuel-core version ${supported.FUEL_CORE}.`,
`Things may not work as expected.`,
].join('\n'),
});
Expand Down
2 changes: 2 additions & 0 deletions packages/account/src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,8 @@ export default class Provider {
`The TS SDK currently supports fuel-core version ${supportedVersion}.`,
`Things may not work as expected.`,
].join('\n');
FuelGraphqlSubscriber.incompatibleNodeVersionMessage =
Provider.incompatibleNodeVersionMessage;
}
}

Expand Down
37 changes: 37 additions & 0 deletions packages/account/test/utils/mockIncompabileVersions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as fuelTsVersionsMod from '@fuel-ts/versions';
import { versions } from '@fuel-ts/versions';

export const mockIncompatibleVersions = (opts: {
isMajorMismatch: boolean;
isMinorMismatch: boolean;
}) => {
const mismatch = (current: string) => (current === '0' ? 1 : parseInt(current, 10) - 1);

const { isMajorMismatch, isMinorMismatch } = opts;
const { FUEL_CORE } = versions;
const [currentMajor, currentMinor, currentPatch] = FUEL_CORE.split('.');
const [major, minor, patch] = [
isMajorMismatch ? mismatch(currentMajor) : currentMajor,
isMinorMismatch ? mismatch(currentMinor) : currentMinor,
currentPatch,
].map(String);

const mock = {
isMajorSupported: major !== currentMajor,
isMinorSupported: minor !== currentMinor,
isPatchSupported: patch !== currentPatch,
supportedVersion: `${major}.${minor}.${patch}`,
};

if (mock.supportedVersion === FUEL_CORE) {
throw new Error();
}

const spy = vi.spyOn(fuelTsVersionsMod, 'checkFuelCoreVersionCompatibility');
spy.mockImplementationOnce(() => mock);

return {
current: { FUEL_CORE },
supported: { FUEL_CORE: mock.supportedVersion },
};
};

0 comments on commit 2914c67

Please sign in to comment.