본문으로 건너뛰기

오류 형식화

Zod는 오류 보고에서 _완전성_과 _정확성_을 중시합니다. 많은 경우 $ZodError를 더 유용한 형식으로 변환하면 도움이 됩니다. Zod는 이를 위한 몇 가지 유틸리티를 제공합니다.

다음과 같은 간단한 객체 스키마를 살펴보겠습니다.

import * as z from "zod";

const schema = z.strictObject({
username: z.string(),
favoriteNumbers: z.array(z.number()),
});

이 유효하지 않은 데이터를 파싱하면 세 개의 이슈가 포함된 오류가 발생합니다.

const result = schema.safeParse({
username: 1234,
favoriteNumbers: [1234, "4567"],
extraKey: 1234,
});

result.error!.issues;
[
{
expected: 'string',
code: 'invalid_type',
path: [ 'username' ],
message: 'Invalid input: expected string, received number'
},
{
expected: 'number',
code: 'invalid_type',
path: [ 'favoriteNumbers', 1 ],
message: 'Invalid input: expected number, received string'
},
{
code: 'unrecognized_keys',
keys: [ 'extraKey' ],
path: [],
message: 'Unrecognized key: "extraKey"'
}
];

z.treeifyError()

이 오류를 중첩 객체로 변환("트리화")하려면 z.treeifyError()를 사용합니다.

const tree = z.treeifyError(result.error);

// =>
{
errors: [ 'Unrecognized key: "extraKey"' ],
properties: {
username: { errors: [ 'Invalid input: expected string, received number' ] },
favoriteNumbers: {
errors: [],
items: [
undefined,
{
errors: [ 'Invalid input: expected number, received string' ]
}
]
}
}
}

결과는 스키마 자체를 그대로 반영하는 중첩 구조입니다. 특정 경로에서 발생한 오류에 쉽게 접근할 수 있습니다. errors 필드에는 해당 경로의 오류 메시지가 들어 있으며, 특수 속성인 propertiesitems를 사용해 트리의 더 깊은 곳을 탐색할 수 있습니다.

tree.properties?.username?.errors;
// => ["Invalid input: expected string, received number"]

tree.properties?.favoriteNumbers?.items?.[1]?.errors;
// => ["Invalid input: expected number, received string"];

중첩 속성에 접근할 때 오류가 발생하지 않도록 선택적 체이닝(?.)을 사용하세요.

z.prettifyError()

z.prettifyError()는 오류를 사람이 읽기 쉬운 문자열로 표현합니다.

const pretty = z.prettifyError(result.error);

이 함수는 다음 문자열을 반환합니다.

✖ Unrecognized key: "extraKey"
✖ Invalid input: expected string, received number
→ at username
✖ Invalid input: expected number, received string
→ at favoriteNumbers[1]

z.formatError()

문서 보기

오류를 중첩 객체로 변환하려면 다음과 같이 합니다.

const formatted = z.formatError(result.error);

// returns:
{
_errors: [ 'Unrecognized key: "extraKey"' ],
username: { _errors: [ 'Invalid input: expected string, received number' ] },
favoriteNumbers: {
'1': { _errors: [ 'Invalid input: expected number, received string' ] },
_errors: []
}
}

결과는 스키마 자체를 그대로 반영하는 중첩 구조입니다. 특정 경로에서 발생한 오류에 쉽게 접근할 수 있습니다.

formatted?.username?._errors;
// => ["Invalid input: expected string, received number"]

formatted?.favoriteNumbers?.[1]?._errors;
// => ["Invalid input: expected number, received string"]

중첩 속성에 접근할 때 오류가 발생하지 않도록 선택적 체이닝(?.)을 사용하세요.

z.flattenError()

z.treeifyError()는 복잡한 중첩 구조를 탐색할 때 유용하지만, 대부분의 스키마는 깊이가 한 단계뿐인 평면 구조입니다. 이 경우 z.flattenError()를 사용해 간결한 최상위 오류 객체를 가져옵니다.

const flattened = z.flattenError(result.error);
// { errors: string[], properties: { [key: string]: string[] } }

{
formErrors: [ 'Unrecognized key: "extraKey"' ],
fieldErrors: {
username: [ 'Invalid input: expected string, received number' ],
favoriteNumbers: [ 'Invalid input: expected number, received string' ]
}
}

formErrors 배열에는 모든 최상위 오류(path[]인 오류)가 들어 있습니다. fieldErrors 객체는 스키마의 각 필드에 대한 오류 배열을 제공합니다.

flattened.fieldErrors.username; // => [ 'Invalid input: expected string, received number' ]
flattened.fieldErrors.favoriteNumbers; // => [ 'Invalid input: expected number, received string' ]