错误处理
非官方测试版翻译
本页面由 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 仅在 isDev 为 true 时包含 error.data.stack。
initTRPC.create() 默认将 isDev 设置为 process.env.NODE_ENV !== 'production'。
如需在不同运行时环境下保持确定性行为,请手动覆盖 isDev 的值。
server.tstsimport {initTRPC } from '@trpc/server';constt =initTRPC .create ({isDev : false });
server.tstsimport {initTRPC } from '@trpc/server';constt =initTRPC .create ({isDev : false });
如需更严格地控制返回的错误字段,请使用错误格式化。
错误代码
tRPC 定义了一组错误代码,每个代码代表不同类型的错误,并对应不同的 HTTP 状态码。
| Code | Description | HTTP code |
|---|---|---|
| PARSE_ERROR | Invalid JSON was received by the server, or an error occurred while parsing the request. | 400 |
| BAD_REQUEST | The server cannot or will not process the request due to something that is perceived to be a client error. | 400 |
| UNAUTHORIZED | The client request has not been completed because it lacks valid authentication credentials for the requested resource. | 401 |
| PAYMENT_REQUIRED | The client request requires payment to access the requested resource. | 402 |
| FORBIDDEN | The client is not authorized to access the requested resource. | 403 |
| NOT_FOUND | The server cannot find the requested resource. | 404 |
| METHOD_NOT_SUPPORTED | The server knows the request method, but the target resource doesn't support this method. | 405 |
| TIMEOUT | The server would like to shut down this unused connection. | 408 |
| CONFLICT | The request conflicts with the current state of the target resource. | 409 |
| PRECONDITION_FAILED | Access to the target resource has been denied. | 412 |
| PAYLOAD_TOO_LARGE | Request entity is larger than limits defined by server. | 413 |
| UNSUPPORTED_MEDIA_TYPE | The server refuses to accept the request because the payload format is in an unsupported format. | 415 |
| UNPROCESSABLE_CONTENT | The server understands the request method, and the request entity is correct, but the server was unable to process it. | 422 |
| PRECONDITION_REQUIRED | The 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_REQUESTS | The rate limit has been exceeded or too many requests are being sent to the server. | 429 |
| CLIENT_CLOSED_REQUEST | The client closed the connection before the server finished responding. | 499 |
| INTERNAL_SERVER_ERROR | An unspecified error occurred. | 500 |
| NOT_IMPLEMENTED | The server does not support the functionality required to fulfill the request. | 501 |
| BAD_GATEWAY | The server received an invalid response from the upstream server. | 502 |
| SERVICE_UNAVAILABLE | The server is not ready to handle the request. | 503 |
| GATEWAY_TIMEOUT | The server did not get a response in time from the upstream server that it needed in order to complete the request. | 504 |
tRPC 提供了辅助函数 getHTTPStatusCodeFromError,用于从错误中提取 HTTP 状态码:
tsimport {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}
tsimport {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}
技巧
关于服务端上下文中的错误处理完整示例,请参阅服务端调用文档。
抛出错误
tRPC 提供了 TRPCError 错误子类,用于表示在过程中发生的错误。
例如,抛出以下错误:
server.tstsimport {initTRPC ,TRPCError } from '@trpc/server';constt =initTRPC .create ();consttheError = newError ('something went wrong');constappRouter =t .router ({hello :t .procedure .query (() => {throw newTRPCError ({code : 'INTERNAL_SERVER_ERROR',message : 'An unexpected error occurred, please try again later.',// optional: pass the original error to retain stack tracecause :theError ,});}),});// [...]
server.tstsimport {initTRPC ,TRPCError } from '@trpc/server';constt =initTRPC .create ();consttheError = newError ('something went wrong');constappRouter =t .router ({hello :t .procedure .query (() => {throw newTRPCError ({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 方法处理,再发送给客户端。您可以在此处处理错误(修改错误格式请参阅错误格式化)。
server.tstsimport {createHTTPServer } from '@trpc/server/adapters/standalone';import {appRouter } from './router';constserver =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.tstsimport {createHTTPServer } from '@trpc/server/adapters/standalone';import {appRouter } from './router';constserver =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 参数是一个包含错误本身及其上下文所有信息的对象:
tsinterfaceOnErrorOpts {error :TRPCError ;type : 'query' | 'mutation' | 'subscription' | 'unknown';path : string | undefined;input : unknown;ctx : unknown;req :Request ;}
tsinterfaceOnErrorOpts {error :TRPCError ;type : 'query' | 'mutation' | 'subscription' | 'unknown';path : string | undefined;input : unknown;ctx : unknown;req :Request ;}