Skip to content

Commit f00f7e6

Browse files
fix: better error handling
1 parent be232fa commit f00f7e6

File tree

8 files changed

+34
-30
lines changed

8 files changed

+34
-30
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,4 @@
123123
"vitest": "^3.2.4"
124124
},
125125
"packageManager": "pnpm@10.0.0"
126-
}
126+
}

src/handlers.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import type { StandardSchemaV1 } from "@standard-schema/spec";
22
import { quansync } from "quansync";
33
import { getToJsonSchemaFn } from "./vendors/index.js";
44
import {
5-
errorMessageWrapper,
65
type ToJsonSchemaFn,
6+
UnsupportedVendorError,
77
validationMapper,
88
} from "./vendors/utils.js";
99

@@ -12,14 +12,11 @@ import {
1212
*/
1313
export const toJsonSchema = quansync({
1414
sync: (schema: StandardSchemaV1, options?: Record<string, unknown>) => {
15-
const fn = validationMapper.get(schema["~standard"].vendor);
15+
const vendor = schema["~standard"].vendor;
16+
const fn = validationMapper.get(vendor);
1617

1718
if (!fn) {
18-
throw new Error(
19-
errorMessageWrapper(
20-
`Unsupported schema vendor "${schema["~standard"].vendor}".`,
21-
),
22-
);
19+
throw new UnsupportedVendorError(vendor);
2320
}
2421

2522
return fn(schema, options);

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
export * from "./handlers.js";
2-
export type { ToJsonSchemaFn } from "./vendors/utils.js";
2+
export type { ToJsonSchemaFn } from "./vendors/utils.js";

src/vendors/effect.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import type { Schema } from "effect";
22
import type { JSONSchema7 } from "json-schema";
3-
import { errorMessageWrapper, type ToJsonSchemaFn } from "./utils.js";
3+
import { MissingDependencyError, type ToJsonSchemaFn } from "./utils.js";
44

55
export default async function getToJsonSchemaFn(): Promise<ToJsonSchemaFn> {
66
try {
77
const { JSONSchema } = await import("effect");
88
return (schema) =>
99
JSONSchema.make(schema as Schema.Schema<unknown>) as JSONSchema7;
1010
} catch {
11-
throw new Error(errorMessageWrapper('Missing dependencies "effect".'));
11+
throw new MissingDependencyError("effect");
1212
}
1313
}

src/vendors/index.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {
2-
errorMessageWrapper,
32
type ToJsonSchemaFn,
3+
UnsupportedVendorError,
44
validationMapper,
55
} from "./utils.js";
66

@@ -28,9 +28,7 @@ export const getToJsonSchemaFn = async (
2828
vendorFnPromise = (await import("./zod.js")).default();
2929
break;
3030
default:
31-
throw new Error(
32-
errorMessageWrapper(`Unsupported schema vendor "${vendor}".`),
33-
);
31+
throw new UnsupportedVendorError(vendor);
3432
}
3533

3634
const vendorFn = await vendorFnPromise;

src/vendors/utils.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,16 @@ export type ToJsonSchemaFn = (
44
options?: Record<string, unknown>,
55
) => JSONSchema7 | Promise<JSONSchema7>;
66

7-
export const errorMessageWrapper = (message: string) =>
8-
`standard-json: ${message}`;
9-
107
export const validationMapper = new Map<string, ToJsonSchemaFn>();
8+
9+
export class UnsupportedVendorError extends Error {
10+
constructor(vendor: string) {
11+
super(`standard-json: Unsupported schema vendor "${vendor}".`);
12+
}
13+
}
14+
15+
export class MissingDependencyError extends Error {
16+
constructor(packageName: string) {
17+
super(`standard-json: Missing dependencies "${packageName}".`);
18+
}
19+
}

src/vendors/valibot.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import { errorMessageWrapper, type ToJsonSchemaFn } from "./utils.js";
1+
import { MissingDependencyError, type ToJsonSchemaFn } from "./utils.js";
22

33
export default async function getToJsonSchemaFn(): Promise<ToJsonSchemaFn> {
44
try {
55
const { toJsonSchema } = await import("@valibot/to-json-schema");
66
return toJsonSchema as ToJsonSchemaFn;
77
} catch {
8-
throw new Error(
9-
errorMessageWrapper('Missing dependencies "@valibot/to-json-schema".'),
10-
);
8+
throw new MissingDependencyError("@valibot/to-json-schema");
119
}
1210
}

src/vendors/zod.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { ZodTypeAny } from "zod/v3";
22
import type { $ZodType } from "zod/v4/core";
3-
import { errorMessageWrapper, type ToJsonSchemaFn } from "./utils.js";
3+
import { MissingDependencyError, type ToJsonSchemaFn } from "./utils.js";
4+
5+
const zodv4Error = new MissingDependencyError("zod v4");
46

57
export default async function getToJsonSchemaFn(): Promise<ToJsonSchemaFn> {
68
return async (schema, options) => {
@@ -9,21 +11,21 @@ export default async function getToJsonSchemaFn(): Promise<ToJsonSchemaFn> {
911
// https://zod.dev/library-authors?id=how-to-support-zod-and-zod-mini-simultaneously#how-to-support-zod-3-and-zod-4-simultaneously
1012
if ("_zod" in (schema as $ZodType | ZodTypeAny)) {
1113
try {
12-
handler = await import("zod/v4/core").then(
13-
(mod) => mod.toJSONSchema as ToJsonSchemaFn,
14-
);
14+
handler = await import("zod/v4/core")
15+
.catch(() => {
16+
throw zodv4Error;
17+
})
18+
.then((mod) => mod.toJSONSchema as ToJsonSchemaFn);
1519
} catch {
16-
throw new Error(errorMessageWrapper('Missing dependencies "zod v4".'));
20+
throw zodv4Error;
1721
}
1822
} else {
1923
try {
2024
handler = await import("zod-to-json-schema").then(
2125
(mod) => mod.zodToJsonSchema as ToJsonSchemaFn,
2226
);
2327
} catch {
24-
throw new Error(
25-
errorMessageWrapper('Missing dependencies "zod-to-json-schema".'),
26-
);
28+
throw new MissingDependencyError("zod-to-json-schema");
2729
}
2830
}
2931

0 commit comments

Comments
 (0)