Add type guard for Yup ValidationError before accessing inner property#1000
Conversation
|
|
…erty Co-authored-by: levalleux-ludo <7184124+levalleux-ludo@users.noreply.github.com>
Co-authored-by: levalleux-ludo <7184124+levalleux-ludo@users.noreply.github.com>
033ea70
into
998-check-exchangepolicy-for-bundle
There was a problem hiding this comment.
Pull request overview
This PR improves error handling in the checkExchangePolicy function by adding a type guard to safely check for Yup ValidationError with an inner array before accessing it. This prevents potential runtime failures when non-Yup errors are thrown during validation.
Changes:
- Added
isValidationErrorWithInner()type guard function to safely detect Yup ValidationError objects - Updated two catch blocks to use the type guard with fallback error handling for non-Yup errors
- Minor package-lock.json update (yaml package marked as peer dependency)
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| packages/core-sdk/src/offers/checkExchangePolicy.ts | Adds type guard function and applies it to validation error handling in two catch blocks with fallback error structures |
| package-lock.json | Automatic lockfile update marking yaml as peer dependency (unrelated to main PR changes) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }) || [] | ||
| isValidationErrorWithInner(e) | ||
| ? e.inner.map((error) => { | ||
| return { ...error }; |
There was a problem hiding this comment.
When spreading Yup ValidationError objects with the spread operator, additional properties beyond message, path, and value may be copied into the result. While this may not cause immediate issues, it could lead to unexpected behavior if the result is strictly validated elsewhere or if consumers rely on the type definition. Consider explicitly mapping only the expected properties to ensure the result structure exactly matches the CheckExchangePolicyResult type.
| return { ...error }; | |
| return { | |
| message: error.message, | |
| path: error.path ?? "", | |
| value: error.value | |
| }; |
| : [ | ||
| { | ||
| message: | ||
| e instanceof Error ? e.message : "Validation failed with unknown error", | ||
| path: "", | ||
| value: undefined | ||
| } | ||
| ] |
There was a problem hiding this comment.
There are no test cases covering the new error handling path for non-Yup ValidationError scenarios. The fallback error handling (lines 128-135 and 171-180) that returns "Validation failed with unknown error" is not tested. Consider adding test cases to verify that errors without the inner property are handled correctly and return the expected error structure.
| ): error is { inner: Array<{ message: string; path?: string; value?: unknown }> } { | ||
| return ( | ||
| typeof error === "object" && | ||
| error !== null && | ||
| "inner" in error && | ||
| Array.isArray((error as { inner: unknown }).inner) | ||
| ); |
There was a problem hiding this comment.
The type guard's return type declares path?: string and value?: unknown as optional, but the CheckExchangePolicyResult type (lines 5-12) requires these properties to be non-optional (path: string and value: unknown). This type mismatch could lead to runtime errors when consumers expect these properties to always be present. Additionally, the type guard only validates that inner is an array but doesn't verify that the array elements have the required structure with a message property.
| ): error is { inner: Array<{ message: string; path?: string; value?: unknown }> } { | |
| return ( | |
| typeof error === "object" && | |
| error !== null && | |
| "inner" in error && | |
| Array.isArray((error as { inner: unknown }).inner) | |
| ); | |
| ): error is { inner: Array<{ message: string; path: string; value: unknown }> } { | |
| if ( | |
| typeof error !== "object" || | |
| error === null || | |
| !("inner" in error) || | |
| !Array.isArray((error as { inner: unknown }).inner) | |
| ) { | |
| return false; | |
| } | |
| const { inner } = error as { inner: unknown[] }; | |
| return inner.every((item) => { | |
| if (typeof item !== "object" || item === null) { | |
| return false; | |
| } | |
| const candidate = item as { | |
| message?: unknown; | |
| path?: unknown; | |
| value?: unknown; | |
| }; | |
| return ( | |
| typeof candidate.message === "string" && | |
| typeof candidate.path === "string" && | |
| "value" in candidate | |
| ); | |
| }); |
| ? e.inner.map((error) => { | ||
| return { ...error }; | ||
| }) |
There was a problem hiding this comment.
When spreading Yup ValidationError objects with the spread operator, additional properties beyond message, path, and value may be copied into the result. While this may not cause immediate issues, it could lead to unexpected behavior if the result is strictly validated elsewhere or if consumers rely on the type definition. Consider explicitly mapping only the expected properties to ensure the result structure exactly matches the CheckExchangePolicyResult type.
| ? e.inner.map((error) => { | |
| return { ...error }; | |
| }) | |
| ? e.inner.map((error) => ({ | |
| message: error.message, | |
| path: error.path ?? "", | |
| value: error.value | |
| })) |
* feat: adapt check exchange policy for bundle offers * fix exchangePolicy name/version/returnPeriod in OfferPolicyDetails when bundle offer * Update packages/react-kit/src/hooks/useCheckExchangePolicy.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update packages/core-sdk/src/offers/checkExchangePolicy.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update packages/core-sdk/src/offers/checkExchangePolicy.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * copilot pr remarks * Update packages/react-kit/src/components/offerPolicy/OfferPolicyDetails.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update packages/react-kit/src/hooks/useCheckExchangePolicy.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * copilot pr remarks * copilot pr remarks * copilot pr remarks * Update packages/core-sdk/src/offers/checkExchangePolicy.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update packages/core-sdk/src/offers/checkExchangePolicy.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update packages/react-kit/src/components/offerPolicy/OfferPolicyDetails.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update data/exchangePolicies/exchangePolicyRules.template.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update packages/core-sdk/src/offers/checkExchangePolicy.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add type guard for Yup ValidationError before accessing inner property (#1000) * Initial plan * Add type checking for Yup ValidationError before accessing inner property Co-authored-by: levalleux-ludo <7184124+levalleux-ludo@users.noreply.github.com> * Fix spacing in function call Co-authored-by: levalleux-ludo <7184124+levalleux-ludo@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: levalleux-ludo <7184124+levalleux-ludo@users.noreply.github.com> * chore: add defensive error type checking for yup validationError handling (#1001) * Initial plan * Add error type checking for Yup ValidationError handling Co-authored-by: levalleux-ludo <7184124+levalleux-ludo@users.noreply.github.com> * Refactor: extract error validation logic into helper function Co-authored-by: levalleux-ludo <7184124+levalleux-ludo@users.noreply.github.com> * Improve error property extraction to be more explicit Co-authored-by: levalleux-ludo <7184124+levalleux-ludo@users.noreply.github.com> * Improve type safety in error extraction helper Co-authored-by: levalleux-ludo <7184124+levalleux-ludo@users.noreply.github.com> * Add comprehensive JSDoc documentation for error extraction helper Co-authored-by: levalleux-ludo <7184124+levalleux-ludo@users.noreply.github.com> * fix lint * fix test --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: levalleux-ludo <7184124+levalleux-ludo@users.noreply.github.com> Co-authored-by: Ludovic Levalleux <levalleux_ludo@hotmail.com> * copilot pr remarks * some additional fixes * fix render contractual agreement for bundle offer --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: levalleux-ludo <7184124+levalleux-ludo@users.noreply.github.com>
The code accessed
e.innerwithout verifying the error type, risking runtime failures if non-Yup errors are thrown during validation.Changes
isValidationErrorWithInner()to safely check for Yup ValidationError withinnerarrayinnerproperty💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.