causaly / zod-validation-error

Wrap zod validation errors in user-friendly readable messages
MIT License
789 stars 11 forks source link

Provide isZodErrorLike helper? #374

Closed mmkal closed 2 weeks ago

mmkal commented 2 weeks ago

Hi! This library is great, but there's a helper I find myself needing to write myself for it when I use it - a check to see if an error is a zod error in the first place. This will help with code like this where we don't actually know if an error is a zod error or something else:

const Person = z.object({ name: z.string() })

const greetPerson = (input: unknown) => {
  if (Math.random() < 0.5) throw new Error('unlucky')

  const person = Person.parse(input)
  console.log('Hi ' + person.name)
}

const run = () => {
  try {
    const input = getInputFromSomewhere()
    greetPerson(input)
  } catch (e) {
    if (isZodErrorLike(e)) {
      throw fromZodError(e)
    }
    throw e // leave non-zod errors alone
  }
}

For the same reasons that using instanceof is a bad idea on ValidationError, it's even worse on ZodError because there are so many dependencies on zod, it's quite likely that you'll end up with the wrong one.

I've used this in trpc-cli:

export const looksLikeInstanceof = <T>(value: unknown, target: new (...args: any[]) => T): value is T => {
  let current = value?.constructor
  do {
    if (current?.name === target.name) return true
    current = Object.getPrototypeOf(current) as Function
  } while (current?.name)
  return false
}

That covers inheritance too, which it looks like isValidationErrorLike doesn't right now: https://github.com/causaly/zod-validation-error/blob/60b423086edb78b7d7678317196906fbbe6221da/lib/isValidationErrorLike.ts#L3-L5

guillaumebrunerie commented 2 weeks ago

isZodErrorLike does exist already (but doesn’t seem documented).

jmike commented 2 weeks ago

Correct, it exists already but it's not documented. Let us fix this.

jmike commented 2 weeks ago

@mmkal have a look at this PR (https://github.com/causaly/zod-validation-error/pull/378)

mmkal commented 2 weeks ago

Great! Thanks