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

오류 처리

프로시저에서 오류가 발생하면 tRPC는 "error" 속성을 포함한 객체를 클라이언트에 응답합니다. 이 속성에는 클라이언트에서 오류를 처리하는 데 필요한 모든 정보가 포함됩니다.

잘못된 요청 입력으로 인해 발생하는 오류 응답의 예시는 다음과 같습니다:

json
{
"id": null,
"error": {
"message": "\"password\" must be at least 4 characters",
"code": -32600,
"data": {
"code": "BAD_REQUEST",
"httpStatus": 400,
"stack": "...",
"path": "user.changepassword"
}
}
}
json
{
"id": null,
"error": {
"message": "\"password\" must be at least 4 characters",
"code": -32600,
"data": {
"code": "BAD_REQUEST",
"httpStatus": 400,
"stack": "...",
"path": "user.changepassword"
}
}
}

프로덕션 환경의 스택 트레이스

기본적으로 tRPC는 isDevtrue일 때만 error.data.stack을 포함합니다. initTRPC.create()는 기본적으로 isDevprocess.env.NODE_ENV !== 'production'으로 설정합니다. 런타임 간에 결정적인 동작이 필요하면 isDev를 수동으로 오버라이드하세요.

server.ts
ts
import { initTRPC } from '@trpc/server';
 
const t = initTRPC.create({ isDev: false });
server.ts
ts
import { initTRPC } from '@trpc/server';
 
const t = initTRPC.create({ isDev: false });

반환되는 오류 필드에 대한 더 엄격한 제어가 필요하면 오류 포맷팅을 사용하세요.

오류 코드

tRPC는 서로 다른 유형의 오류를 나타내고 서로 다른 HTTP 코드로 응답하는 오류 코드 목록을 정의합니다.

코드설명HTTP 코드
PARSE_ERROR서버가 잘못된 JSON을 수신했거나 요청을 파싱하는 동안 오류가 발생했습니다.400
BAD_REQUEST클라이언트 오류로 간주되는 이유로 인해 서버가 요청을 처리할 수 없거나 처리하지 않습니다.400
UNAUTHORIZED요청된 리소스에 대한 유효한 인증 자격 증명이 없으므로 클라이언트 요청이 완료되지 않았습니다.401
PAYMENT_REQUIRED요청된 리소스에 액세스하려면 클라이언트 요청에 결제가 필요합니다.402
FORBIDDEN클라이언트는 요청된 리소스에 액세스할 권한이 없습니다.403
NOT_FOUND서버가 요청된 리소스를 찾을 수 없습니다.404
METHOD_NOT_SUPPORTED서버가 요청 메서드를 알고 있지만 대상 리소스에서 이 메서드를 지원하지 않습니다.405
TIMEOUT서버가 사용되지 않는 연결을 종료하려고 합니다.408
CONFLICT요청이 대상 리소스의 현재 상태와 충돌합니다.409
PRECONDITION_FAILED대상 리소스에 대한 액세스가 거부되었습니다.412
PAYLOAD_TOO_LARGE요청 엔티티가 서버에서 정의한 한도를 초과했습니다.413
UNSUPPORTED_MEDIA_TYPE페이로드 형식이 지원되지 않는 형식이므로 서버가 요청을 수락하기를 거부합니다.415
UNPROCESSABLE_CONTENT서버는 요청 메서드를 이해하고 요청 엔티티가 정확하지만 처리할 수 없었습니다.422
PRECONDITION_REQUIRED필수 전제 조건 헤더(예: If-Match)가 없으므로 서버가 요청을 처리할 수 없습니다. 전제 조건 헤더가 서버 측 상태와 일치하지 않으면 응답은 412 Precondition Failed이어야 합니다.428
TOO_MANY_REQUESTS속도 제한이 초과되었거나 서버로 너무 많은 요청이 전송되고 있습니다.429
CLIENT_CLOSED_REQUEST서버가 응답을 완료하기 전에 클라이언트가 연결을 닫았습니다.499
INTERNAL_SERVER_ERROR지정되지 않은 오류가 발생했습니다.500
NOT_IMPLEMENTED서버는 요청을 충족하는 데 필요한 기능을 지원하지 않습니다.501
BAD_GATEWAY서버가 업스트림 서버에서 잘못된 응답을 수신했습니다.502
SERVICE_UNAVAILABLE서버는 요청을 처리할 준비가 되어 있지 않습니다.503
GATEWAY_TIMEOUT요청을 완료하는 데 필요한 업스트림 서버로부터 제시간에 응답을 받지 못했습니다.504

tRPC는 오류에서 HTTP 코드를 추출하는 데 도움을 주는 getHTTPStatusCodeFromError 헬퍼 함수를 제공합니다:

ts
import { getHTTPStatusCodeFromError } from '@trpc/server/http';
 
// Example error you might get if your input validation fails
const error: TRPCError = {
name: 'TRPCError',
code: 'BAD_REQUEST',
message: '"password" must be at least 4 characters',
};
 
if (error instanceof TRPCError) {
const httpCode = getHTTPStatusCodeFromError(error);
console.log(httpCode); // 400
}
ts
import { getHTTPStatusCodeFromError } from '@trpc/server/http';
 
// Example error you might get if your input validation fails
const error: TRPCError = {
name: 'TRPCError',
code: 'BAD_REQUEST',
message: '"password" must be at least 4 characters',
};
 
if (error instanceof TRPCError) {
const httpCode = getHTTPStatusCodeFromError(error);
console.log(httpCode); // 400
}

서버 사이드 컨텍스트에서 오류 처리가 작동하는 방식에 대한 전체 예제는 서버 사이드 호출 문서에서 확인할 수 있습니다.

오류 발생

tRPC는 프로시저 내에서 발생한 오류를 나타내는 데 사용할 수 있는 오류 하위 클래스 TRPCError를 제공합니다.

예를 들어, 이 오류를 발생시키면:

server.ts
ts
import { initTRPC, TRPCError } from '@trpc/server';
 
const t = initTRPC.create();
 
const theError = new Error('something went wrong');
 
const appRouter = t.router({
hello: t.procedure.query(() => {
throw new TRPCError({
code: 'INTERNAL_SERVER_ERROR',
message: 'An unexpected error occurred, please try again later.',
// optional: pass the original error to retain stack trace
cause: theError,
});
}),
});
 
// [...]
server.ts
ts
import { initTRPC, TRPCError } from '@trpc/server';
 
const t = initTRPC.create();
 
const theError = new Error('something went wrong');
 
const appRouter = t.router({
hello: t.procedure.query(() => {
throw new TRPCError({
code: 'INTERNAL_SERVER_ERROR',
message: 'An unexpected error occurred, please try again later.',
// optional: pass the original error to retain stack trace
cause: theError,
});
}),
});
 
// [...]

다음과 같은 응답이 생성됩니다:

json
{
"id": null,
"error": {
"message": "An unexpected error occurred, please try again later.",
"code": -32603,
"data": {
"code": "INTERNAL_SERVER_ERROR",
"httpStatus": 500,
"stack": "...",
"path": "hello"
}
}
}
json
{
"id": null,
"error": {
"message": "An unexpected error occurred, please try again later.",
"code": -32603,
"data": {
"code": "INTERNAL_SERVER_ERROR",
"httpStatus": 500,
"stack": "...",
"path": "hello"
}
}
}

오류 처리

프로시저에서 발생하는 모든 오류는 클라이언트로 전송되기 전에 onError 메서드를 거칩니다. 여기서 오류를 처리할 수 있습니다(오류 형식을 변경하려면 오류 포맷팅을 참조하세요).

server.ts
ts
import { createHTTPServer } from '@trpc/server/adapters/standalone';
import { appRouter } from './router';
 
const server = createHTTPServer({
router: appRouter,
onError(opts) {
const { error, type, path, input, ctx, req } = opts;
console.error('Error:', error);
if (error.code === 'INTERNAL_SERVER_ERROR') {
// send to bug reporting
}
},
});
server.ts
ts
import { createHTTPServer } from '@trpc/server/adapters/standalone';
import { appRouter } from './router';
 
const server = createHTTPServer({
router: appRouter,
onError(opts) {
const { error, type, path, input, ctx, req } = opts;
console.error('Error:', error);
if (error.code === 'INTERNAL_SERVER_ERROR') {
// send to bug reporting
}
},
});

onError 매개변수는 오류에 대한 모든 정보와 해당 오류가 발생한 컨텍스트를 포함하는 객체입니다:

ts
interface OnErrorOpts {
error: TRPCError;
type: 'query' | 'mutation' | 'subscription' | 'unknown';
path: string | undefined;
input: unknown;
ctx: unknown;
req: Request;
}
ts
interface OnErrorOpts {
error: TRPCError;
type: 'query' | 'mutation' | 'subscription' | 'unknown';
path: string | undefined;
input: unknown;
ctx: unknown;
req: Request;
}