본문 바로가기
버전: 11.x

오류 처리

비공식 베타 번역

이 페이지는 PageTurner AI로 번역되었습니다(베타). 프로젝트 공식 승인을 받지 않았습니다. 오류를 발견하셨나요? 문제 신고 →

프로시저에서 오류가 발생하면 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 코드로 응답하는 오류 코드 목록을 정의합니다.

CodeDescriptionHTTP code
PARSE_ERRORInvalid JSON was received by the server, or an error occurred while parsing the request.400
BAD_REQUESTThe server cannot or will not process the request due to something that is perceived to be a client error.400
UNAUTHORIZEDThe client request has not been completed because it lacks valid authentication credentials for the requested resource.401
PAYMENT_REQUIREDThe client request requires payment to access the requested resource.402
FORBIDDENThe client is not authorized to access the requested resource.403
NOT_FOUNDThe server cannot find the requested resource.404
METHOD_NOT_SUPPORTEDThe server knows the request method, but the target resource doesn't support this method.405
TIMEOUTThe server would like to shut down this unused connection.408
CONFLICTThe request conflicts with the current state of the target resource.409
PRECONDITION_FAILEDAccess to the target resource has been denied.412
PAYLOAD_TOO_LARGERequest entity is larger than limits defined by server.413
UNSUPPORTED_MEDIA_TYPEThe server refuses to accept the request because the payload format is in an unsupported format.415
UNPROCESSABLE_CONTENTThe server understands the request method, and the request entity is correct, but the server was unable to process it.422
PRECONDITION_REQUIREDThe server cannot process the request because a required precondition header (such as If-Match) is missing. When a precondition header does not match the server-side state, the response should be 412 Precondition Failed.428
TOO_MANY_REQUESTSThe rate limit has been exceeded or too many requests are being sent to the server.429
CLIENT_CLOSED_REQUESTThe client closed the connection before the server finished responding.499
INTERNAL_SERVER_ERRORAn unspecified error occurred.500
NOT_IMPLEMENTEDThe server does not support the functionality required to fulfill the request.501
BAD_GATEWAYThe server received an invalid response from the upstream server.502
SERVICE_UNAVAILABLEThe server is not ready to handle the request.503
GATEWAY_TIMEOUTThe server did not get a response in time from the upstream server that it needed in order to complete the request.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;
}