Skip to content

Commit ed63598

Browse files
authored
Merge pull request #2 from useVenice/master
Fix compile issue, pass error shape, and unwrap more zod types
2 parents a064393 + e05e07b commit ed63598

File tree

4 files changed

+59
-34
lines changed

4 files changed

+59
-34
lines changed

src/adapters/node-http/core.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ export const createOpenApiNodeHttpHandler = <
173173
const statusCode = meta?.status ?? TRPC_ERROR_CODE_HTTP_STATUS[error.code] ?? 500;
174174
const headers = meta?.headers ?? {};
175175
const body: OpenApiErrorResponse = {
176+
...errorShape, // Pass the error through
176177
message: isInputValidationError
177178
? 'Input validation failed'
178179
: errorShape?.message ?? error.message ?? 'An error occurred',

src/generator/schema.ts

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -140,43 +140,54 @@ export const getRequestBodyObject = (
140140
export const hasInputs = (schema: unknown) =>
141141
instanceofZodType(schema) && !instanceofZodTypeLikeVoid(unwrapZodType(schema, true));
142142

143+
const errorResponseObjectByCode: Record<string, ZodOpenApiResponseObject> = {};
144+
143145
export const errorResponseObject = (
144-
code?: string,
146+
code = 'INTERNAL_SERVER_ERROR',
145147
message?: string,
146148
issues?: { message: string }[],
147-
): ZodOpenApiResponseObject => ({
148-
description: message ?? 'An error response',
149-
content: {
150-
'application/json': {
151-
schema: z
152-
.object({
153-
message: z.string().openapi({
154-
description: 'The error message',
155-
example: message ?? 'Internal server error',
156-
}),
157-
code: z
158-
.string()
159-
.openapi({ description: 'The error code', example: code ?? 'INTERNAL_SERVER_ERROR' }),
160-
issues: z
161-
.array(z.object({ message: z.string() }))
162-
.optional()
149+
): ZodOpenApiResponseObject => {
150+
if (!errorResponseObjectByCode[code]) {
151+
errorResponseObjectByCode[code] = {
152+
description: message ?? 'An error response',
153+
content: {
154+
'application/json': {
155+
schema: z
156+
.object({
157+
message: z.string().openapi({
158+
description: 'The error message',
159+
example: message ?? 'Internal server error',
160+
}),
161+
code: z
162+
.string()
163+
.openapi({
164+
description: 'The error code',
165+
example: code ?? 'INTERNAL_SERVER_ERROR',
166+
}),
167+
issues: z
168+
.array(z.object({ message: z.string() }))
169+
.optional()
170+
.openapi({
171+
description: 'An array of issues that were responsible for the error',
172+
example: issues ?? [],
173+
}),
174+
})
163175
.openapi({
164-
description: 'An array of issues that were responsible for the error',
165-
example: issues ?? [],
176+
title: 'Error',
177+
description: 'The error information',
178+
example: {
179+
code: code ?? 'INTERNAL_SERVER_ERROR',
180+
message: message ?? 'Internal server error',
181+
issues: issues ?? [],
182+
},
183+
ref: `error.${code}`,
166184
}),
167-
})
168-
.openapi({
169-
title: 'Error',
170-
description: 'The error information',
171-
example: {
172-
code: code ?? 'INTERNAL_SERVER_ERROR',
173-
message: message ?? 'Internal server error',
174-
issues: issues ?? [],
175-
},
176-
}),
177-
},
178-
},
179-
});
185+
},
186+
},
187+
};
188+
}
189+
return errorResponseObjectByCode[code]!;
190+
};
180191

181192
export const errorResponseFromStatusCode = (status: number) => {
182193
const code = HTTP_STATUS_TRPC_ERROR_CODE[status];

src/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Procedure, ProcedureParams, Router } from '@trpc/server';
22
import type { RootConfig } from '@trpc/server/dist/core/internals/config';
3-
import { TRPC_ERROR_CODE_KEY } from '@trpc/server/rpc';
4-
import type { RouterDef } from '@trpc/server/src/core/router';
3+
import type { RouterDef } from '@trpc/server/dist/core/router';
4+
import { TRPC_ERROR_CODE_KEY } from '@trpc/server/dist/rpc';
55
import {
66
AnyZodObject,
77
ZodBigInt,

src/utils/zod.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ export const instanceofZodTypeLikeVoid = (type: z.ZodTypeAny): type is ZodTypeLi
3232
};
3333

3434
export const unwrapZodType = (type: z.ZodTypeAny, unwrapPreprocess: boolean): z.ZodTypeAny => {
35+
// TODO: Allow parsing array query params
36+
// if (instanceofZodTypeKind(type, z.ZodFirstPartyTypeKind.ZodArray)) {
37+
// return unwrapZodType(type.element, unwrapPreprocess);
38+
// }
39+
if (instanceofZodTypeKind(type, z.ZodFirstPartyTypeKind.ZodEnum)) {
40+
return unwrapZodType(z.string(), unwrapPreprocess);
41+
}
42+
if (instanceofZodTypeKind(type, z.ZodFirstPartyTypeKind.ZodNullable)) {
43+
return unwrapZodType(type.unwrap(), unwrapPreprocess);
44+
}
45+
if (instanceofZodTypeKind(type, z.ZodFirstPartyTypeKind.ZodBranded)) {
46+
return unwrapZodType(type.unwrap(), unwrapPreprocess);
47+
}
3548
if (instanceofZodTypeKind(type, z.ZodFirstPartyTypeKind.ZodOptional)) {
3649
return unwrapZodType(type.unwrap(), unwrapPreprocess);
3750
}

0 commit comments

Comments
 (0)