feat(server): 新增统一 logger 入口与 /health liveness 端点
- src/server/logger.ts 包一层 console.*,给后续 pino/otel 迁移留单点 - interceptors.ts 的 logError 改走 logger.error,业务侧禁止直接 console.* - /health 返回 'ok',纯 liveness(不查 DB),DB 挂时探活仍绿
This commit is contained in:
+21
-3
@@ -9,10 +9,16 @@
|
||||
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
||||
|
||||
import { Route as rootRouteImport } from './routes/__root'
|
||||
import { Route as HealthRouteImport } from './routes/health'
|
||||
import { Route as IndexRouteImport } from './routes/index'
|
||||
import { Route as ApiSplatRouteImport } from './routes/api/$'
|
||||
import { Route as ApiRpcSplatRouteImport } from './routes/api/rpc.$'
|
||||
|
||||
const HealthRoute = HealthRouteImport.update({
|
||||
id: '/health',
|
||||
path: '/health',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const IndexRoute = IndexRouteImport.update({
|
||||
id: '/',
|
||||
path: '/',
|
||||
@@ -31,36 +37,47 @@ const ApiRpcSplatRoute = ApiRpcSplatRouteImport.update({
|
||||
|
||||
export interface FileRoutesByFullPath {
|
||||
'/': typeof IndexRoute
|
||||
'/health': typeof HealthRoute
|
||||
'/api/$': typeof ApiSplatRoute
|
||||
'/api/rpc/$': typeof ApiRpcSplatRoute
|
||||
}
|
||||
export interface FileRoutesByTo {
|
||||
'/': typeof IndexRoute
|
||||
'/health': typeof HealthRoute
|
||||
'/api/$': typeof ApiSplatRoute
|
||||
'/api/rpc/$': typeof ApiRpcSplatRoute
|
||||
}
|
||||
export interface FileRoutesById {
|
||||
__root__: typeof rootRouteImport
|
||||
'/': typeof IndexRoute
|
||||
'/health': typeof HealthRoute
|
||||
'/api/$': typeof ApiSplatRoute
|
||||
'/api/rpc/$': typeof ApiRpcSplatRoute
|
||||
}
|
||||
export interface FileRouteTypes {
|
||||
fileRoutesByFullPath: FileRoutesByFullPath
|
||||
fullPaths: '/' | '/api/$' | '/api/rpc/$'
|
||||
fullPaths: '/' | '/health' | '/api/$' | '/api/rpc/$'
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
to: '/' | '/api/$' | '/api/rpc/$'
|
||||
id: '__root__' | '/' | '/api/$' | '/api/rpc/$'
|
||||
to: '/' | '/health' | '/api/$' | '/api/rpc/$'
|
||||
id: '__root__' | '/' | '/health' | '/api/$' | '/api/rpc/$'
|
||||
fileRoutesById: FileRoutesById
|
||||
}
|
||||
export interface RootRouteChildren {
|
||||
IndexRoute: typeof IndexRoute
|
||||
HealthRoute: typeof HealthRoute
|
||||
ApiSplatRoute: typeof ApiSplatRoute
|
||||
ApiRpcSplatRoute: typeof ApiRpcSplatRoute
|
||||
}
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
interface FileRoutesByPath {
|
||||
'/health': {
|
||||
id: '/health'
|
||||
path: '/health'
|
||||
fullPath: '/health'
|
||||
preLoaderRoute: typeof HealthRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/': {
|
||||
id: '/'
|
||||
path: '/'
|
||||
@@ -87,6 +104,7 @@ declare module '@tanstack/react-router' {
|
||||
|
||||
const rootRouteChildren: RootRouteChildren = {
|
||||
IndexRoute: IndexRoute,
|
||||
HealthRoute: HealthRoute,
|
||||
ApiSplatRoute: ApiSplatRoute,
|
||||
ApiRpcSplatRoute: ApiRpcSplatRoute,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
|
||||
export const Route = createFileRoute('/health')({
|
||||
server: {
|
||||
handlers: {
|
||||
GET: () => new Response('ok', { status: 200, headers: { 'content-type': 'text/plain' } }),
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -1,13 +1,14 @@
|
||||
import { ORPCError, ValidationError } from '@orpc/server'
|
||||
import { z } from 'zod'
|
||||
import { logger } from '@/server/logger'
|
||||
|
||||
export const logError = (error: unknown) => {
|
||||
console.error(error)
|
||||
logger.error(error)
|
||||
}
|
||||
|
||||
export const handleValidationError = (error: unknown) => {
|
||||
if (error instanceof ORPCError && error.code === 'BAD_REQUEST' && error.cause instanceof ValidationError) {
|
||||
// If you only use Zod you can safely cast to ZodIssue[] (per ORPC official docs)
|
||||
// ORPC ValidationError.issues are Zod issues in this app.
|
||||
const zodError = new z.ZodError(error.cause.issues as z.core.$ZodIssue[])
|
||||
|
||||
throw new ORPCError('INPUT_VALIDATION_FAILED', {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export const logger = {
|
||||
error: (error: unknown) => console.error(error),
|
||||
warn: (...args: unknown[]) => console.warn(...args),
|
||||
info: (...args: unknown[]) => console.info(...args),
|
||||
}
|
||||
Reference in New Issue
Block a user