feat(react-lang): expand parser validation with rule-tagged errors#350
Conversation
Adds three new validation checks to ParseResult.meta.validationErrors: - unknown-component: PascalCase name not found in the library schema - excess-args: more positional args passed than the schema defines - unresolved-ref: identifier referenced but never assigned (one-shot and stream-end only — forward refs are valid mid-stream) Also adds: - ValidationError.rule discriminant field for consumer-side filtering - ValidationRule type exported from the parser index - StreamParser.finalize() to signal stream completion and trigger unresolved-ref promotion Existing missing-required and null-required errors now carry rule tags. Rendering behavior is unchanged — the parser stays permissive. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds vitest and 17 tests covering the three new validation checks: - unknown-component: unknown PascalCase names are reported, element still renders - excess-args: extra positional args reported, component still renders - unresolved-ref: promoted to validationErrors in one-shot and on finalize(), but not mid-stream (forward refs are valid during streaming) Also tests that existing missing-required and null-required errors carry the new rule field. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add StreamParser.finalize() docs with usage note about when to call it - Add ValidationRule type and table of all rule values - Add ValidationError.rule field to type signatures - Add filtering example showing consumer-side rule usage - Update README types import list to include ValidationError, ValidationRule Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@AbhinRustagi Thanks for improving the validation handling, we were also planning to address these issues. I took a quick look at the PR and will review it in detail when I get some time. At the moment, everything looks good to me except for the finalize part, which I’m not entirely sure about, let me think more about it. The original idea was that developers would check validation errors only once after the entire streaming is complete, rather than on every chunk. Once streaming is done, we can then check for validation errors and handle them gracefully. |
|
Sure @Aditya-thesys ! Happy to help brainstorm it. My rationale behind the |
|
Makes sense. I’m a bit hesitant to overload type OpenUIError =
| { type: "validation"; code: "missing-required" | "null-required" | "unknown-component" | "excess-args"; ... }
| { type: "parser"; code: "incomplete" | "unresolved-ref"; ... };now checking |
|
@Aditya-thesys Sounds good. On a second thought, do you think we can keep Essentially, we can document how the consumer can check for the unresolved refs -> either check for elements in |
|
The |
|
@Aditya-thesys Okay, I will update the PR to remove |
|
yes it is close, also i am not sure where will you add error handling in the documentation, |
|
I was thinking of adding a Guides section to OpenUI page because the error handling is supposed to be suggestive and a how-to of how the library offers visibility on errors, and not a strict mandate. |
|
makes sense, but we haven't documented much about our parser. We expect devs to use The issue is that |
…UIError type Remove finalize() and unresolved-ref error promotion per reviewer feedback. Rename validationErrors → errors, use type+code discriminated union for forward-compatible error taxonomy. Update tests and api-reference docs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@Aditya-thesys Updated the PR to the latest discussion |
There was a problem hiding this comment.
Lg, thanks for the contribution @AbhinRustagi 🙌
please run the lint, build is failing due to it.
|
@Aditya-thesys fixed ✅ |
Summary
Closes #349
ParseResult.meta.errors:unknown-component,excess-args, and the existingmissing-required/null-requiredrulesValidationError/ValidationRulewith a discriminatedOpenUIErrortype usingtype+codefields — extensible for futuretype: "parser"diagnosticsmeta.validationErrors→meta.errorsStreamParser.finalize()— unresolved references stay inmeta.unresolvedfor consumers to check after streaming endsOpenUIErrorandValidationErrorCodetypes from the package indexRendering behavior is unchanged — the parser stays permissive and renders what it can.
Test plan
pnpm testinpackages/react-lang— 16 tests, all passingunknown-component: parseroot = DataTable("col")withDataTableabsent from schema →errorscontains{ type: "validation", code: "unknown-component" }excess-args: parseroot = Title("a", "b")whereTitletakes 1 arg →errorscontains{ type: "validation", code: "excess-args" }meta.unresolvedwithout producing errors (both one-shot and streaming)missing-requiredandnull-requirederrors carry newtype/codeshapetsc --noEmit)🤖 Generated with Claude Code