diff --git a/.changeset/bright-laws-relax.md b/.changeset/bright-laws-relax.md new file mode 100644 index 000000000..d9951bf48 --- /dev/null +++ b/.changeset/bright-laws-relax.md @@ -0,0 +1,5 @@ +--- +'@farfetched/core': minor +--- + +Allow passing array of codes to `isHttpErrorCode` diff --git a/apps/website/docs/api/utils/error_guards.md b/apps/website/docs/api/utils/error_guards.md index 5bcd0287a..9833af1d4 100644 --- a/apps/website/docs/api/utils/error_guards.md +++ b/apps/website/docs/api/utils/error_guards.md @@ -71,7 +71,11 @@ const httpError = sample({ ### `isHttpErrorCode` -This function is a more specific version of `isHttpError`. It takes a number as an argument and returns a function that checks if the error is a `HttpError` with the given status code. +This function is a more specific version of `isHttpError`. + +#### `isHttpErrorCode(statusCode: number)` + +It takes a number as an argument and returns a function that checks if the error is a `HttpError` with the given status code. ```ts import { isHttpErrorCode } from '@farfetched/core'; @@ -82,6 +86,19 @@ const notFound = sample({ }); ``` +#### `isHttpErrorCode(statusCodes: number[])` + +It takes an array of numbers as an argument and returns a function that checks if the error is a `HttpError` with one of the given status codes. + +```ts +import { isHttpErrorCode } from '@farfetched/core'; + +const notFoundOrForbidden = sample({ + clock: query.finished.failure, + filter: isHttpErrorCode([404, 403]), +}); +``` + ## `isNetworkError` `NetworkError` is thrown when the query fails because of network problems. diff --git a/packages/core/src/errors/__test__/guards.test.ts b/packages/core/src/errors/__test__/guards.test.ts new file mode 100644 index 000000000..b09b70a28 --- /dev/null +++ b/packages/core/src/errors/__test__/guards.test.ts @@ -0,0 +1,50 @@ +import { describe, test, expect } from 'vitest'; +import { httpError } from '../create_error'; + +import { isHttpErrorCode } from '../guards'; + +describe('isHttpErrorCode', () => { + test('isHttpErrorCode supports array of codes', () => { + const check401or403 = isHttpErrorCode([401, 403]); + + expect( + check401or403({ + error: httpError({ + status: 401, + statusText: 'Text', + response: {}, + }), + }) + ).toBe(true); + + expect( + check401or403({ + error: httpError({ + status: 403, + statusText: 'Text', + response: {}, + }), + }) + ).toBe(true); + + expect( + check401or403({ + error: httpError({ + status: 400, + statusText: 'Text', + response: {}, + }), + }) + ).toBe(false); + + expect( + check401or403({ + error: httpError({ + status: 404, + statusText: 'Text', + response: {}, + }), + }) + ).toBe(false); + }); +}); diff --git a/packages/core/src/errors/guards.ts b/packages/core/src/errors/guards.ts index 5b74bfa30..7022c97e6 100644 --- a/packages/core/src/errors/guards.ts +++ b/packages/core/src/errors/guards.ts @@ -1,9 +1,9 @@ import { ABORT, - AbortError, + type AbortError, HTTP, - HttpError, - InvalidDataError, + type HttpError, + type InvalidDataError, INVALID_DATA, NETWORK, NetworkError, @@ -41,7 +41,7 @@ export function isHttpError(args: WithError): args is WithError { return args.error?.errorType === HTTP; } -export function isHttpErrorCode(code: Code) { +export function isHttpErrorCode(code: Code | Code[]) { return function isExactHttpError( args: WithError ): args is WithError> { @@ -49,7 +49,9 @@ export function isHttpErrorCode(code: Code) { return false; } - return args.error.status === code; + const codes = Array.isArray(code) ? code : [code]; + + return codes.includes(args.error.status as any); }; }