错误处理
每当过程发生错误时,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 failsconsterror :TRPCError = {name : 'TRPCError',code : 'BAD_REQUEST',message : '"password" must be at least 4 characters',};if (error instanceofTRPCError ) {consthttpCode =getHTTPStatusCodeFromError (error );console .log (httpCode ); // 400}
ts
import {getHTTPStatusCodeFromError } from '@trpc/server/http';// Example error you might get if your input validation failsconsterror :TRPCError = {name : 'TRPCError',code : 'BAD_REQUEST',message : '"password" must be at least 4 characters',};if (error instanceofTRPCError ) {consthttpCode =getHTTPStatusCodeFromError (error );console .log (httpCode ); // 400}
提示
在 服务器端调用文档 中有一个关于如何在 Next.js API 端点中使用此方法的完整示例。
抛出错误
tRPC 提供了一个错误子类 TRPCError
,您可以使用它来表示在过程内部发生的错误。
例如,抛出此错误
server.tsts
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 tracecause: theError,});}),});// [...]
server.tsts
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 tracecause: 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].tsts
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].tsts
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 errortype: 'query' | 'mutation' | 'subscription' | 'unknown';path: string | undefined; // path of the procedure that was triggeredinput: unknown;ctx: Context | undefined;req: BaseRequest; // request object}
ts
{error: TRPCError; // the original errortype: 'query' | 'mutation' | 'subscription' | 'unknown';path: string | undefined; // path of the procedure that was triggeredinput: unknown;ctx: Context | undefined;req: BaseRequest; // request object}