Skip to content

Commit

Permalink
feat: better error handlers
Browse files Browse the repository at this point in the history
A new package, @nftx/errors allows for a much more fine grained error system and easier handling/recovering/displaying of errors in the UI
  • Loading branch information
jackmellis committed Nov 22, 2023
1 parent 1b54b6a commit 7674e25
Show file tree
Hide file tree
Showing 58 changed files with 620 additions and 163 deletions.
1 change: 1 addition & 0 deletions packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"prepublishOnly": "yarn build"
},
"dependencies": {
"@nftx/errors": "^0.9.4",
"@nftx/config": "^0.9.0",
"@nftx/types": "^0.9.0",
"@nftx/utils": "^0.9.0",
Expand Down
5 changes: 4 additions & 1 deletion packages/api/src/assets/fetchAllAssets.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Address, Asset } from '@nftx/types';
import { BadRequestError } from '@nftx/errors';
import streamAssets from './streamAssets';
import type {
CollectionAssetsArgs,
Expand Down Expand Up @@ -45,7 +46,9 @@ function fetchAllAssets({
if (assetAddress) {
return streamAssets({ assetAddress, network });
}
throw new Error('Must provide userAddress, vaultId, or assetAddress');
throw new BadRequestError(
'Must provide userAddress, vaultId, or assetAddress'
);
})();

stream.on('error', rej);
Expand Down
5 changes: 4 additions & 1 deletion packages/api/src/assets/streamAssets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import fetchAssets, {
UserAssetsArgs,
VaultAssetsArgs,
} from './fetchAssets';
import { BadRequestError } from '@nftx/errors';

/** Stream assets owned by a user */
function streamAssets(args: Omit<UserAssetsArgs, 'cursor'>): IStream<Asset[]>;
Expand Down Expand Up @@ -51,7 +52,9 @@ function streamAssets({
if (assetAddress) {
return fetchAssets({ assetAddress, cursor, network });
}
throw new Error();
throw new BadRequestError(
'Must be provide either userAddress, vaultId, or assetAddress'
);
})();

cursor = result.cursor;
Expand Down
3 changes: 3 additions & 0 deletions packages/constants/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,8 @@
},
"bugs": {
"url": "https://github.com/NFTX-project/nftxjs/issues"
},
"dependencies": {
"@nftx/errors": "^0.9.4"
}
}
14 changes: 11 additions & 3 deletions packages/constants/src/feeTiers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ValidationError } from '@nftx/errors';

/** 0.3% | 1% | 3% */
export type FeeTier = 3_000 | 10_000 | 30_000;
export type FeePercentage = 0 | 0.003 | 0.01 | 0.03;
Expand All @@ -17,7 +19,9 @@ export const percentageToFeeTier = (feePercentage: number): FeeTier => {
case 0.03:
return 30_000;
default:
throw new Error(`Invalid fee percentage: "${feePercentage}"`);
throw new ValidationError({
feePercentage: `Invalid fee percentage: "${feePercentage}"`,
});
}
};

Expand All @@ -30,7 +34,9 @@ export const feeTierToPercentage = (feeTier: number): FeePercentage => {
case 30000:
return 0.03;
default:
throw 0;
throw new ValidationError({
feeTier: `Invalid fee tier: "${feeTier}"`,
});
}
};

Expand All @@ -43,6 +49,8 @@ export const feeTierToTickSpacing = (feeTier: number): FeeTickSpacing => {
case 30000:
return 600;
default:
throw new Error(`Invalid fee tier: "${feeTier}"`);
throw new ValidationError({
feeTier: `Invalid fee tier: "${feeTier}"`,
});
}
};
2 changes: 1 addition & 1 deletion packages/constants/src/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Network } from './networks';

export const NFTX_ROUTER_URL = {
[Network.Goerli]:
'https://cdtl2od0t3.execute-api.eu-central-1.amazonaws.com/prod/quote',
'https://lmw8qdcm7e.execute-api.eu-central-1.amazonaws.com/prod/quote',
};

export const NFTX_APR_URL = {
Expand Down
7 changes: 4 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@
},
"dependencies": {
"@nftx/abi": "^0.9.0",
"@nftx/config": "^0.9.5",
"@nftx/constants": "^0.9.5",
"@nftx/subgraph": "^0.9.5",
"@nftx/config": "^0.9.0",
"@nftx/constants": "^0.9.0",
"@nftx/errors": "^0.9.4",
"@nftx/subgraph": "^0.9.0",
"@nftx/trade": "^0.9.0",
"@nftx/types": "^0.9.0",
"@nftx/utils": "^0.9.0",
Expand Down
11 changes: 2 additions & 9 deletions packages/core/src/assets/fetchUserAssets/fetchUserAssets.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import config from '@nftx/config';
import type { Address, Asset, Provider, Vault } from '@nftx/types';
import { fetchVaults } from '../../vaults';
import fetchAssetsFromReservoir from './fetchAssetsFromReservoir';

type FetchVaults = typeof fetchVaults;
type FetchAssetsFromReservoir = typeof fetchAssetsFromReservoir;

const isDefined = <T>(x: T | undefined): x is T => x != null;

const makeFetchUserAssets = ({
fetchAssetsFromReservoir,
fetchVaults,
}: {
fetchVaults: FetchVaults;
fetchAssetsFromReservoir: FetchAssetsFromReservoir;
}) => {
/** Fetch a user's assets from reservoir */
Expand All @@ -23,24 +19,22 @@ const makeFetchUserAssets = ({
vaultIds,
cursor,
provider,
vaults: givenVaults,
vaults,
}: {
network?: number;
assetAddresses?: Address[];
vaultIds?: string[];
userAddress: Address;
cursor?: string;
provider: Provider;
vaults?: Pick<
vaults: Pick<
Vault,
'asset' | 'features' | 'eligibilityModule' | 'vaultId'
>[];
}): Promise<{
assets: Asset[];
cursor?: string;
}> {
const vaults = givenVaults ?? (await fetchVaults({ provider, network }));

if (vaultIds) {
assetAddresses = vaultIds
.map((vaultId) => vaults.find((v) => v.vaultId === vaultId)?.asset.id)
Expand Down Expand Up @@ -73,5 +67,4 @@ const makeFetchUserAssets = ({

export default makeFetchUserAssets({
fetchAssetsFromReservoir,
fetchVaults,
});
2 changes: 1 addition & 1 deletion packages/core/src/pools/fetchInventoryPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const makeFetchInventoryPool =
network?: number;
vaultId: string;
provider: Provider;
vaults?: Pick<Vault, 'vaultId' | 'id' | 'vTokenToEth'>[];
vaults: Pick<Vault, 'vaultId' | 'id' | 'vTokenToEth'>[];
}) => {
const pools = await fetchInventoryPools({
network,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type {
Vault,
VaultFeeReceipt,
} from '@nftx/types';
import { fetchVaults } from '../../vaults';
import { fetchInventoryPositions } from '../../positions';
import filterVaults from './filterVaults';
import transformPool from './transformPool';
Expand All @@ -21,20 +20,18 @@ const fetchInventoryPools = async ({
vaultAddresses,
vaultIds,
provider,
vaults: givenVaults,
vaults: allVaults,
feeReceipts: givenFeeReceipts,
positions: givenPositions,
}: {
network?: number;
vaultAddresses?: Address[];
vaultIds?: string[];
provider: Provider;
vaults?: Pick<Vault, 'vaultId' | 'id' | 'vTokenToEth'>[];
vaults: Pick<Vault, 'vaultId' | 'id' | 'vTokenToEth'>[];
feeReceipts?: VaultFeeReceipt[];
positions?: InventoryPosition[];
}): Promise<InventoryPool[]> => {
const allVaults = givenVaults ?? (await fetchVaults({ network, provider }));

const vaults = filterVaults({
vaults: allVaults,
vaultAddresses,
Expand All @@ -51,7 +48,6 @@ const fetchInventoryPools = async ({
const positions =
givenPositions ??
(await fetchInventoryPositions({
provider,
network,
vaultIds: vaults.map((v) => v.vaultId),
vaults: allVaults,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/pools/fetchLiquidityPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const makeFetchLiquidityPool =
network?: number;
poolId: Address;
provider: Provider;
vaults?: Pick<Vault, 'id' | 'vaultId' | 'vTokenToEth' | 'token'>[];
vaults: Pick<Vault, 'id' | 'vaultId' | 'vTokenToEth' | 'token'>[];
}) => {
const pools = await fetchLiquidityPools({
network,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import config from '@nftx/config';
import type { Address, LiquidityPool, Provider, Vault } from '@nftx/types';
import { fetchVaults } from '../../vaults';
import fetchPoolsSet from './fetchPoolsSet';
import stubMissingPools from './stubMissingPools';

Expand All @@ -9,7 +8,7 @@ const fetchLiquidityPools = async ({
vaultIds,
vaultAddresses,
poolIds,
vaults: givenVaults,
vaults,
provider,
}: {
network?: number;
Expand All @@ -18,11 +17,9 @@ const fetchLiquidityPools = async ({
/** Only return pools for specific vault ids */
vaultIds?: string[];
poolIds?: Address[];
vaults?: Pick<Vault, 'vaultId' | 'id' | 'vTokenToEth' | 'token'>[];
vaults: Pick<Vault, 'vaultId' | 'id' | 'vTokenToEth' | 'token'>[];
provider: Provider;
}): Promise<LiquidityPool[]> => {
const vaults = givenVaults ?? (await fetchVaults({ network, provider }));

const pools: LiquidityPool[] = [];
let lastId: Address | undefined;

Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/pools/fetchLiquidityPools/fetchPoolsSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Address, Vault } from '@nftx/types';
import queryPoolData from './queryPoolData';
import transformPool from './transformPool';
import { addressEqual } from '@nftx/utils';
import { NotFoundError } from '@nftx/errors';

const getVaultByTokens = <V extends Pick<Vault, 'id'>>({
inputTokens,
Expand All @@ -18,7 +19,7 @@ const getVaultByTokens = <V extends Pick<Vault, 'id'>>({
});
});
if (vault == null) {
throw new Error(`Could not find vault for position ${pool.id}`);
throw new NotFoundError('vault for position', pool.id);
}
return vault;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const fetchPoolAddress = async ({
args: [vaultAddress, feeTier],
});

return poolAddress;
return poolAddress.toLowerCase() as Address;
};

const createStub = ({
Expand Down
10 changes: 6 additions & 4 deletions packages/core/src/positions/fetchInventoryPosition.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Address, InventoryPosition, Provider } from '@nftx/types';
import type { Address, InventoryPosition, Provider, Vault } from '@nftx/types';
import fetchInventoryPositions from './fetchInventoryPositions';

type FetchInventoryPositions = typeof fetchInventoryPositions;
Expand All @@ -12,32 +12,34 @@ export const makeFetchInventoryPosition = ({
network?: number;
provider: Provider;
positionId: Address;
vaults: Pick<Vault, 'id' | 'vaultId' | 'vTokenToEth'>[];
}): Promise<InventoryPosition>;
function fetchPosition(args: {
network?: number;
provider: Provider;
userAddress: Address;
vaultId: string;
vaults: Pick<Vault, 'id' | 'vaultId' | 'vTokenToEth'>[];
}): Promise<InventoryPosition>;
async function fetchPosition({
provider,
network,
positionId,
userAddress,
vaultId,
vaults,
}: {
network?: number;
provider: Provider;
userAddress?: Address;
vaultId?: string;
positionId?: Address;
vaults: Pick<Vault, 'id' | 'vaultId' | 'vTokenToEth'>[];
}) {
const [position] = await fetchInventoryPositions({
network,
provider,
positionIds: positionId ? [positionId] : undefined,
userAddresses: userAddress ? [userAddress] : undefined,
vaultIds: vaultId ? [vaultId] : undefined,
vaults,
});

return position;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import config from '@nftx/config';
import type { Address, InventoryPosition, Provider, Vault } from '@nftx/types';
import { fetchVaults } from '../../vaults';
import type { Address, InventoryPosition, Vault } from '@nftx/types';
import fetchPositionsSet from './fetchPositionsSet';
import { WeiPerEther, Zero } from '@nftx/constants';

Expand Down Expand Up @@ -41,20 +40,17 @@ function updatePoolShares(positions: InventoryPosition[]) {

const fetchInventoryPositions = async ({
network = config.network,
provider,
positionIds,
userAddresses,
vaultIds,
vaults: givenVaults,
vaults,
}: {
userAddresses?: Address[];
vaultIds?: string[];
positionIds?: Address[];
network?: number;
provider: Provider;
vaults?: Pick<Vault, 'id' | 'vaultId' | 'vTokenToEth'>[];
vaults: Pick<Vault, 'id' | 'vaultId' | 'vTokenToEth'>[];
}): Promise<InventoryPosition[]> => {
const vaults = givenVaults ?? (await fetchVaults({ network, provider }));
const vaultAddresses = getVaultAddressesForVaultIds(vaults, vaultIds);

const positions: InventoryPosition[] = [];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Address, Vault } from '@nftx/types';
import { NotFoundError } from '@nftx/errors';
import queryPositionData from './queryPositionData';
import transformPosition from './transformPosition';

Expand All @@ -8,7 +9,7 @@ const getVaultByVaultId = <V extends Pick<Vault, 'vaultId'>>(
) => {
const vault = vaults.find((vault) => vault.vaultId === vaultId);
if (vault == null) {
throw new Error(`Could not find vault ${vaultId}`);
throw new NotFoundError('vault', vaultId);
}
return vault;
};
Expand Down
9 changes: 5 additions & 4 deletions packages/core/src/positions/fetchLiquidityPosition.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import config from '@nftx/config';
import type { Address, Provider } from '@nftx/types';
import type { Address, Vault } from '@nftx/types';
import fetchLiquidityPositions from './fetchLiquidityPositions';

type FetchLiquidityPositions = typeof fetchLiquidityPositions;
Expand All @@ -13,15 +13,16 @@ export const makeFetchLiquidityPosition = ({
async function fetchLiquidityPosition({
positionId,
network = config.network,
provider,
vaults,
}: {
positionId: Address;
provider: Provider;
network?: number;
vaults: Pick<Vault, 'vaultId' | 'id' | 'vTokenToEth'>[];
}) {
const [position] = await fetchLiquidityPositions({
provider,
network,
positionIds: [positionId],
vaults,
});
return position;
};
Expand Down
Loading

0 comments on commit 7674e25

Please sign in to comment.