본문으로 건너뛰기
버전: 11.x

재시도 링크

retryLink는 tRPC 클라이언트에서 실패한 작업을 재시도할 수 있게 해주는 링크입니다. 지정한 조건에 따라 요청을 자동으로 다시 시도하므로 네트워크 장애나 서버 오류 같은 일시적인 오류를 원하는 방식으로 처리할 수 있습니다.

@trpc/react-query를 사용한다면 일반적으로 이 링크가 필요하지 않습니다. 재시도 기능이 useQuery()@tanstack/react-queryuseMutation() 훅에 내장되어 있기 때문입니다.

사용법

tRPC 클라이언트를 생성할 때 retryLink를 가져와 links 배열에 추가할 수 있습니다. 이 링크는 요구 사항에 따라 설정에서 다른 링크의 앞이나 뒤에 배치할 수 있습니다.

ts
import { createTRPCClient, httpBatchLink, retryLink } from '@trpc/client';
import type { AppRouter } from './server';
 
const client = createTRPCClient<AppRouter>({
links: [
retryLink({
retry(opts) {
if (
opts.error.data &&
opts.error.data.code !== 'INTERNAL_SERVER_ERROR'
) {
// Don't retry on non-500s
return false;
}
if (opts.op.type !== 'query') {
// Only retry queries
return false;
}
 
// Retry up to 3 times
return opts.attempts <= 3;
},
// Double every attempt, with max of 30 seconds (starting at 1 second)
retryDelayMs: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
}),
httpBatchLink({
url: 'http://localhost:3000',
}),
],
});
ts
import { createTRPCClient, httpBatchLink, retryLink } from '@trpc/client';
import type { AppRouter } from './server';
 
const client = createTRPCClient<AppRouter>({
links: [
retryLink({
retry(opts) {
if (
opts.error.data &&
opts.error.data.code !== 'INTERNAL_SERVER_ERROR'
) {
// Don't retry on non-500s
return false;
}
if (opts.op.type !== 'query') {
// Only retry queries
return false;
}
 
// Retry up to 3 times
return opts.attempts <= 3;
},
// Double every attempt, with max of 30 seconds (starting at 1 second)
retryDelayMs: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
}),
httpBatchLink({
url: 'http://localhost:3000',
}),
],
});

위 예시에서는 httpBatchLink 앞에 retryLink를 추가합니다. retry 함수는 필수이며 재시도 시점을 정의합니다. 이 예시에서는 다음과 같은 동작을 수행합니다:

  • 상태 코드가 500인 TRPCClientError가 발생했거나 유효한 tRPC 오류를 가져오지 못한 경우 요청을 재시도합니다.
  • 요청을 최대 3회까지 재시도합니다.

옵션

ts
interface RetryLinkOptions<TInferrable extends InferrableClientTypes> {
/**
* The retry function
*/
retry: (opts: RetryFnOptions<TInferrable>) => boolean;
/**
* The delay between retries in ms (defaults to 0)
*/
retryDelayMs?: (attempt: number) => number;
}
 
interface RetryFnOptions<TInferrable extends InferrableClientTypes> {
/**
* The operation that failed
*/
op: Operation;
/**
* The error that occurred
*/
error: TRPCClientError<TInferrable>;
/**
* The number of attempts that have been made (including the first call)
*/
attempts: number;
}
ts
interface RetryLinkOptions<TInferrable extends InferrableClientTypes> {
/**
* The retry function
*/
retry: (opts: RetryFnOptions<TInferrable>) => boolean;
/**
* The delay between retries in ms (defaults to 0)
*/
retryDelayMs?: (attempt: number) => number;
}
 
interface RetryFnOptions<TInferrable extends InferrableClientTypes> {
/**
* The operation that failed
*/
op: Operation;
/**
* The error that occurred
*/
error: TRPCClientError<TInferrable>;
/**
* The number of attempts that have been made (including the first call)
*/
attempts: number;
}

tracked() 이벤트 처리

tracked()를 사용하는 구독과 함께 retryLink를 사용할 때, 링크는 재시도 시 마지막으로 알려진 이벤트 ID를 자동으로 포함합니다. 이를 통해 구독이 다시 연결될 때 누락된 이벤트 없이 중단된 위치에서 이어서 진행할 수 있습니다.

예를 들어 httpSubscriptionLink와 함께 서버 전송 이벤트(SSE)를 사용하면, retryLink401 Unauthorized와 같은 오류가 발생했을 때 마지막 이벤트 ID로 자동 재연결합니다.