2025-10-27 03:50:41 +08:00
|
|
|
import z from "zod"
|
2025-06-10 02:01:11 +08:00
|
|
|
|
|
|
|
|
export abstract class NamedError extends Error {
|
2025-09-15 15:12:07 +08:00
|
|
|
abstract schema(): z.core.$ZodType
|
2025-06-10 02:01:11 +08:00
|
|
|
abstract toObject(): { name: string; data: any }
|
|
|
|
|
|
2025-09-15 15:12:07 +08:00
|
|
|
static create<Name extends string, Data extends z.core.$ZodType>(name: Name, data: Data) {
|
2025-06-17 22:27:49 +08:00
|
|
|
const schema = z
|
|
|
|
|
.object({
|
|
|
|
|
name: z.literal(name),
|
|
|
|
|
data,
|
|
|
|
|
})
|
2025-09-15 15:12:07 +08:00
|
|
|
.meta({
|
2025-06-17 22:27:49 +08:00
|
|
|
ref: name,
|
|
|
|
|
})
|
2025-06-10 02:01:11 +08:00
|
|
|
const result = class extends NamedError {
|
2025-06-17 22:27:49 +08:00
|
|
|
public static readonly Schema = schema
|
2025-06-10 02:01:11 +08:00
|
|
|
|
2025-10-14 13:33:25 +08:00
|
|
|
public override readonly name = name as Name
|
2025-06-11 12:21:46 +08:00
|
|
|
|
2025-06-10 02:01:11 +08:00
|
|
|
constructor(
|
|
|
|
|
public readonly data: z.input<Data>,
|
|
|
|
|
options?: ErrorOptions,
|
|
|
|
|
) {
|
|
|
|
|
super(name, options)
|
|
|
|
|
this.name = name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static isInstance(input: any): input is InstanceType<typeof result> {
|
2025-11-03 13:38:56 +08:00
|
|
|
return typeof input === "object" && "name" in input && input.name === name
|
2025-06-10 02:01:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
schema() {
|
2025-06-17 22:27:49 +08:00
|
|
|
return schema
|
2025-06-10 02:01:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toObject() {
|
|
|
|
|
return {
|
|
|
|
|
name: name,
|
|
|
|
|
data: this.data,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-06-11 12:21:46 +08:00
|
|
|
Object.defineProperty(result, "name", { value: name })
|
2025-06-10 02:01:11 +08:00
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static readonly Unknown = NamedError.create(
|
|
|
|
|
"UnknownError",
|
|
|
|
|
z.object({
|
|
|
|
|
message: z.string(),
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
}
|