Conversation
Schema errors are formatted with better-ajv-errors, which pretty-prints the whole dereferenced API definition and parses it into a JSON AST to render code frames. For large definitions this needs many times their size in memory and crashes the process, or fails with "Invalid string length" once the pretty-printed string exceeds the maximum string length, hiding every real validation error. - Skip code frames for definitions of 5,000,000 characters or more (the existing large spec threshold), including definitions that cannot be stringified at all, and report plain `<JSON pointer> <message>` errors. - Add a `validate.errors.codeFrames` option to disable code frames for any definition. Code frames stay the default. - Make reduceAjvErrors linear instead of quadratic, and only drop errors of actual ancestor paths: the substring check also dropped errors of sibling paths that share a prefix (`/parameters/1` and `/parameters/10`).
🦋 Changeset detectedLatest commit: 2290839 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1225
🧰 Changes
Validating a large API definition with schema errors crashed the process with a heap out-of-memory error (see #1225 for the analysis and a reproduction). This PR changes three things in
packages/parser:1. Skip code frames for large definitions (
src/validators/schema.ts)Code frames are rendered by
better-ajv-errors, which pretty-prints the whole dereferenced definition and parses it into a JSON AST. For definitions ofLARGE_SPEC_SIZE_CAP(5,000,000 characters) or more, schema errors are now reported as plain messages instead:<instancePath> <ajv message>, plus the offending property foradditionalProperties/unevaluatedPropertieserrors (whose Ajv message doesn't name it), e.g.additionalErrorsis unchanged.JSON.stringifythrows (it exceeds the maximum string length) now counts as large; previously it counted as small and went straight into the formatter.2. New
validate.errors.codeFramesoption (src/types.ts, README)codeFrames: falsereturns the same plain messages for definitions of any size. The default istrue, so small definitions keep today's output. Above the size threshold code frames are always disabled; the README documents why.3. Linear
reduceAjvErrors(src/lib/reduceAjvErrors.ts)Every recorded
instancePathnow marks itself and its ancestors in aSet, so each error is checked in O(depth) instead of against every recorded error. This also fixes the ancestor check: it usedinstancePath.includes(…), a substring test, so/parameters/1was dropped once/parameters/10was recorded although they are siblings. Only real ancestors are dropped now, so such definitions can report more (correct) errors than before.large-file-memory-leaktest, whose expected message changes from4xx is not expected to be here!tomust NOT have additional properties (4xx); the error count (20 + 1,016) is unchanged.🧬 Testing
test/lib/reduceAjvErrors.test.ts: lineage reduction, one error per path, prefix siblings (fails onmain),$ref/oneOfnoise, 200,000 errors within 5 s (does not finish onmain).test/specs/code-frames-option: code frames by default, plain messages withcodeFrames: false, plain messages when the definition cannot be stringified.large-file-memory-leak: updated expectation, plus a test thatcodeFrames: truecannot force code frames on a large definition.validate()exhausts the heap on large API definitions with schema errors #1225,--max-old-space-size=4096:mainBoth return the same 20 errors plus
additionalErrors.