錯誤處理
每當程序中發生錯誤時,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}