Merge branch 'query-retry' into 'main'
queryClient: retry certain 5xx codes automatically See merge request soapbox-pub/soapbox!3150
This commit is contained in:
commit
967ad7d59c
|
@ -1,10 +1,12 @@
|
||||||
export class HTTPError extends Error {
|
export class HTTPError extends Error {
|
||||||
|
|
||||||
response: Response;
|
response: Response;
|
||||||
|
request: Request;
|
||||||
|
|
||||||
constructor(response: Response) {
|
constructor(response: Response, request: Request) {
|
||||||
super(response.statusText);
|
super(response.statusText);
|
||||||
this.response = response;
|
this.response = response;
|
||||||
|
this.request = request;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -84,7 +84,7 @@ export class MastodonClient {
|
||||||
const response = await this.fetch(request);
|
const response = await this.fetch(request);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new HTTPError(response);
|
throw new HTTPError(response, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { useQuery, UseQueryOptions } from '@tanstack/react-query';
|
||||||
import { useApi } from 'soapbox/hooks';
|
import { useApi } from 'soapbox/hooks';
|
||||||
import { InstanceV1, instanceV1Schema } from 'soapbox/schemas/instance';
|
import { InstanceV1, instanceV1Schema } from 'soapbox/schemas/instance';
|
||||||
|
|
||||||
interface Opts extends Pick<UseQueryOptions<unknown>, 'enabled' | 'retry' | 'retryOnMount' | 'staleTime'> {
|
interface Opts extends Pick<UseQueryOptions<unknown>, 'enabled' | 'retryOnMount' | 'staleTime'> {
|
||||||
/** The base URL of the instance. */
|
/** The base URL of the instance. */
|
||||||
baseUrl?: string;
|
baseUrl?: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { useQuery, UseQueryOptions } from '@tanstack/react-query';
|
||||||
import { useApi } from 'soapbox/hooks';
|
import { useApi } from 'soapbox/hooks';
|
||||||
import { InstanceV2, instanceV2Schema } from 'soapbox/schemas/instance';
|
import { InstanceV2, instanceV2Schema } from 'soapbox/schemas/instance';
|
||||||
|
|
||||||
interface Opts extends Pick<UseQueryOptions<unknown>, 'enabled' | 'retry' | 'retryOnMount' | 'staleTime'> {
|
interface Opts extends Pick<UseQueryOptions<unknown>, 'enabled' | 'retryOnMount' | 'staleTime'> {
|
||||||
/** The base URL of the instance. */
|
/** The base URL of the instance. */
|
||||||
baseUrl?: string;
|
baseUrl?: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,16 +17,8 @@ interface Opts extends Pick<UseQueryOptions<unknown>, 'enabled' | 'retryOnMount'
|
||||||
export function useInstance(opts: Opts = {}) {
|
export function useInstance(opts: Opts = {}) {
|
||||||
const { baseUrl, retryOnMount = false, staleTime = Infinity } = opts;
|
const { baseUrl, retryOnMount = false, staleTime = Infinity } = opts;
|
||||||
|
|
||||||
function retry(failureCount: number, error: Error): boolean {
|
const v2 = useInstanceV2({ baseUrl, retryOnMount, staleTime });
|
||||||
if (error instanceof HTTPError && error.response.status === 404) {
|
const v1 = useInstanceV1({ baseUrl, retryOnMount, staleTime, enabled: v2.isError });
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return failureCount < 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const v2 = useInstanceV2({ baseUrl, retry, retryOnMount, staleTime });
|
|
||||||
const v1 = useInstanceV1({ baseUrl, retry, retryOnMount, staleTime, enabled: v2.isError });
|
|
||||||
|
|
||||||
const instance = useMemo(() => {
|
const instance = useMemo(() => {
|
||||||
if (v2.instance) {
|
if (v2.instance) {
|
||||||
|
|
|
@ -1,12 +1,30 @@
|
||||||
import { QueryClient } from '@tanstack/react-query';
|
import { QueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { HTTPError } from 'soapbox/api/HTTPError';
|
||||||
|
|
||||||
|
/** HTTP response codes to retry. */
|
||||||
|
const RETRY_CODES = [502, 503, 504, 521, 522];
|
||||||
|
|
||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
queries: {
|
queries: {
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
staleTime: 60000, // 1 minute
|
staleTime: 60000, // 1 minute
|
||||||
gcTime: Infinity,
|
gcTime: Infinity,
|
||||||
retry: false,
|
retry(failureCount: number, error: Error): boolean {
|
||||||
|
if (error instanceof HTTPError) {
|
||||||
|
const { response } = error;
|
||||||
|
|
||||||
|
// TODO: Implement Retry-After.
|
||||||
|
// const retryAfter = response.headers.get('Retry-After');
|
||||||
|
|
||||||
|
if (RETRY_CODES.includes(response.status)) {
|
||||||
|
return failureCount < 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue