Skip to content

Commit

Permalink
Make changes to error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
adhityamamallan committed Dec 10, 2024
1 parent fe91339 commit 770e968
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { act } from 'react-dom/test-utils';
import { renderHook, waitFor } from '@/test-utils/rtl';

import useMergedInfiniteQueries from '../use-merged-infinite-queries';
import { UseMergedInfiniteQueriesError } from '../use-merged-infinite-queries-error';
import { type SingleInfiniteQueryOptions } from '../use-merged-infinite-queries.types';

type MockAPIResponse = {
Expand Down Expand Up @@ -105,6 +106,7 @@ describe(useMergedInfiniteQueries.name, () => {
const [mergedResult] = result.current;
expect(mergedResult.data).toStrictEqual([0, 2, 4, 6, 8]);
expect(mergedResult.status).toStrictEqual('error');
expect(mergedResult.error).toBeInstanceOf(UseMergedInfiniteQueriesError);
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export class UseMergedInfiniteQueriesError extends Error {
errors: Array<Error>;
constructor(message: string, errors: Array<Error>, options?: ErrorOptions) {
super(message, options);
this.errors = errors;
this.name = 'UseMergedInfiniteQueriesError';
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { useMemo, useState, useEffect } from 'react';
import { useMemo, useState, useEffect, useCallback } from 'react';

import { InfiniteQueryObserver, useQueryClient } from '@tanstack/react-query';

import mergeSortedArrays from '@/utils/merge-sorted-arrays';

import getMergedFetchNextPage from './helpers/get-merged-fetch-next-page';
import getMergedQueryStatus from './helpers/get-merged-query-status';
import { UseMergedInfiniteQueriesError } from './use-merged-infinite-queries-error';
import {
type SingleInfiniteQueryResult,
type MergedQueriesResults,
Expand All @@ -26,8 +27,8 @@ import {
* @param flattenResult - A function that takes the expected query result and flattens it into an array of items
* @param compare - A comparison function used to sort and merge results.
* The function should accept two arguments and return:
* - A number > 0 if the first argument has a higher priority.
* - A number <= 0 if the second argument has a higher or equal priority.
* - A number > 0 if the second argument comes first.
* - A number <= 0 if the first argument comes first.
* - **Note:** The comparison logic must match the sorting logic used in the queries to maintain consistency.
*
* @returns A tuple [mergedQueryResults, queryResults]:
Expand Down Expand Up @@ -85,6 +86,14 @@ export default function useMergedInfiniteQueries<TData, TResponse, TPageParam>({
});
}, [flattenedDataArrays, count, compare]);

const refetchQueriesWithError = useCallback(() => {
queryResults.forEach((res) => {
if (res.isError) {
res.refetch();
}
});
}, [queryResults]);

const mergedQueryResults = {
data: sortedArray,
status: getMergedQueryStatus(queryResults),
Expand All @@ -99,6 +108,13 @@ export default function useMergedInfiniteQueries<TData, TResponse, TPageParam>({
pageSize,
setCount,
}),
error: queryResults.some((qr) => qr.isError)
? new UseMergedInfiniteQueriesError(
'One or more infinite queries failed',
queryResults.filter((qr) => qr.isError).map((qr) => qr.error)

Check failure on line 114 in src/hooks/use-merged-infinite-queries/use-merged-infinite-queries.ts

View workflow job for this annotation

GitHub Actions / build

Argument of type '(Error | null)[]' is not assignable to parameter of type 'Error[]'.
)
: null,
refetch: refetchQueriesWithError,
// ...add other properties if needed
};
return [mergedQueryResults, queryResults];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
type useInfiniteQuery,
} from '@tanstack/react-query';

import { type UseMergedInfiniteQueriesError } from './use-merged-infinite-queries-error';

export type MergedQueryStatus = 'idle' | 'loading' | 'success' | 'error';

export type MergedQueriesResults<TData> = {
Expand All @@ -15,6 +17,8 @@ export type MergedQueriesResults<TData> = {
isFetchingNextPage: boolean;
hasNextPage: boolean;
fetchNextPage: () => void;
error: UseMergedInfiniteQueriesError | null;
refetch: () => void;
};

export type SingleInfiniteQueryOptions<TResponse, TPageParam> =
Expand Down
13 changes: 12 additions & 1 deletion src/utils/request/request-error.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import { type ZodIssue } from 'zod';

export class RequestError extends Error {
status: number;
constructor(message: string, status: number, options?: ErrorOptions) {
validationErrors: Array<ZodIssue> | undefined;
constructor(
message: string,
status: number,
validationErrors?: Array<ZodIssue>,
options?: ErrorOptions
) {
super(message, options);
this.status = status;
if (validationErrors?.length) {
this.validationErrors = validationErrors;
}
this.name = 'RequestError';
}
}
11 changes: 8 additions & 3 deletions src/utils/request/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@ export default function request(
async (res) => {
if (!res.ok) {
const error = await res.json();
throw new RequestError(error.message, res.status, {
cause: error.cause,
});
throw new RequestError(
error.message,
res.status,
error.validationErrors,
{
cause: error.cause,
}
);
}
return res;
}
Expand Down

0 comments on commit 770e968

Please sign in to comment.