Skip to content

Errors

trpcgo errors carry a tRPC code, a message, an optional cause, and an HTTP status mapping.

return User{}, trpcgo.NewError(trpcgo.CodeNotFound, "user not found")
return nil, trpcgo.NewErrorf(trpcgo.CodeBadRequest, "invalid id: %s", id)
return nil, trpcgo.WrapError(trpcgo.CodeInternalServerError, "database failed", err)

Common codes:

Go constanttRPC nameHTTP status
CodeBadRequestBAD_REQUEST400
CodeUnauthorizedUNAUTHORIZED401
CodeForbiddenFORBIDDEN403
CodeNotFoundNOT_FOUND404
CodeMethodNotSupportedMETHOD_NOT_SUPPORTED405
CodePayloadTooLargePAYLOAD_TOO_LARGE413
CodeTooManyRequestsTOO_MANY_REQUESTS429
CodeInternalServerErrorINTERNAL_SERVER_ERROR500

Other standard tRPC-compatible gateway, timeout, conflict, and precondition codes are also available.

Plain Go errors are converted to INTERNAL_SERVER_ERROR before they reach the client.

Internal errors with causes are masked as internal server error in client responses. WithOnError runs before response formatting and can receive the wrapped cause for server-side logging.

router := trpcgo.NewRouter(
trpcgo.WithOnError(func(ctx context.Context, err *trpcgo.Error, path string) {
log.Printf("trpc error on %s: %v", path, err)
}),
)

WithDev(true) adds Go stack traces to error.data.stack. It does not expose wrapped internal cause messages to clients.

Keep dev mode off in production.

Use WithErrorFormatter to extend or replace the serialized error shape.

router := trpcgo.NewRouter(
trpcgo.WithErrorFormatter(func(input trpcgo.ErrorFormatterInput) any {
return map[string]any{
"error": map[string]any{
"code": input.Shape.Error.Code,
"message": input.Shape.Error.Message,
"data": input.Shape.Error.Data,
"timestamp": time.Now().UTC().Format(time.RFC3339),
},
}
}),
)

ErrorFormatterInput includes the client-safe error, procedure type, path, raw JSON input, request context, and default tRPC error shape.

Errors from output validators or output parsers become INTERNAL_SERVER_ERROR. For subscriptions, trpcgo sends an SSE serialized-error event and closes the stream.