跳至主要内容
版本: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 定义了一个错误代码列表,每个代码代表不同类型的错误,并使用不同的 HTTP 代码进行响应。

代码描述HTTP 代码
BAD_REQUEST由于被认为是客户端错误的原因,服务器无法或不会处理请求。400
UNAUTHORIZED客户端请求未完成,因为它缺少对请求资源的有效身份验证凭据。401
FORBIDDEN服务器无权访问所需的數據源,例如 REST API。403
NOT_FOUND服务器找不到请求的资源。404
TIMEOUT服务器希望关闭此未使用的连接。408
CONFLICT服务器请求资源与目标资源的当前状态冲突。409
PRECONDITION_FAILED拒绝访问目标资源。412
PAYLOAD_TOO_LARGE请求实体大于服务器定义的限制。413
METHOD_NOT_SUPPORTED服务器知道请求方法,但目标资源不支持此方法。405
UNPROCESSABLE_CONTENT服务器理解请求方法,并且请求实体是正确的,但服务器无法处理它。422
TOO_MANY_REQUESTS速率限制已超过,或者正在向服务器发送太多请求。429
CLIENT_CLOSED_REQUEST拒绝访问资源。499
INTERNAL_SERVER_ERROR发生了未指定的错误。500

tRPC 公开了一个辅助函数 getHTTPStatusCodeFromError,可帮助您从错误中提取 HTTP 代码

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
}
提示

服务器端调用文档 中有一个关于如何在 Next.js API 端点中使用此方法的完整示例。

抛出错误

tRPC 提供了一个错误子类 TRPCError,您可以使用它来表示在过程内部发生的错误。

例如,抛出此错误

server.ts
ts
import { initTRPC, TRPCError } from '@trpc/server';
const t = initTRPC.create();
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 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 方法。在这里,您可以处理或更改错误。

pages/api/trpc/[trpc].ts
ts
export default trpcNext.createNextApiHandler({
// ...
onError(opts) {
const { error, type, path, input, ctx, req } = opts;
console.error('Error:', error);
if (error.code === 'INTERNAL_SERVER_ERROR') {
// send to bug reporting
}
},
});
pages/api/trpc/[trpc].ts
ts
export default trpcNext.createNextApiHandler({
// ...
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
{
error: TRPCError; // the original error
type: 'query' | 'mutation' | 'subscription' | 'unknown';
path: string | undefined; // path of the procedure that was triggered
input: unknown;
ctx: Context | undefined;
req: BaseRequest; // request object
}
ts
{
error: TRPCError; // the original error
type: 'query' | 'mutation' | 'subscription' | 'unknown';
path: string | undefined; // path of the procedure that was triggered
input: unknown;
ctx: Context | undefined;
req: BaseRequest; // request object
}