feat: pretty-print and truncate JSON snapshots and type shapes in error messages#2291
feat: pretty-print and truncate JSON snapshots and type shapes in error messages#2291hrastnik wants to merge 1 commit into
Conversation
…or messages Type-checking errors previously serialized the offending snapshot as a single unbroken JSON.stringify line and the target type shape (describe()) as one long line, which is hard to read for large snapshots. - prettyPrintValue: keep small values compact/inline (unchanged), but for large values pretty-print across lines and truncate long strings, big arrays/objects and deep nesting so they don't flood the screen. - prettyPrintDescription: re-indent long model type shapes across lines, while leaving union/array parts inline; defensively falls back to the original string so it can never throw while an error is already being formatted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for the PR, @hrastnik! Just wanted to let you know I've seen this and will try to get to it soon. I've got a busy schedule with some personal stuff but I am on board with the idea. Will just have to review once I find time. |
|
Hey @hrastnik - I like this idea. However, I don't like the idea of hardcoding a preferred format into the codebase itself. What if we allowed for an optional format function in our error checkers, and provided an API for consumers to pass in their preferred formatting (and maybe offer a couple of useful defaults). That way we can make this change strictly opt-in, and flexible for people who want to do something different from these settings. How do you feel about that change? |
coolsoftwaretyler
left a comment
There was a problem hiding this comment.
See prior comment - let's make this solution a bit more flexible.
What does this PR do and why?
If this pull request is approved, it will make type-checking error messages far
easier to read when a large snapshot fails to convert.
Today, a failed conversion serializes the offending snapshot as a single
unbroken
JSON.stringifyline, and renders the target type shape(
type.describe()) as one long line too. For real-world snapshots (arrays ofobjects, long strings) this produces an unreadable wall of text.
This PR improves the formatting in two places, both in
src/core/type/type-checker.ts:prettyPrintValue— small values are still printed compactly on a singleline (unchanged), but large values are now pretty-printed across multiple
lines and truncated: long strings are clipped, big arrays/objects are capped
with a
… N more items/… N more keysmarker, and deep nesting issummarized. This keeps errors from flooding the screen.
prettyPrintDescription— long model type shapes (theexpected ... a snapshot like+ "..." +part) are re-indented across lines, while union (|) and array ([]`) parts stay inline. It is writtendefensively: it never throws (it runs while an error is already being
formatted) and falls back to the original string on any unexpected input.
Before
After
Small values and short type shapes are unchanged, so existing behavior (and the
existing assertions in the test suite) are preserved.
Steps to validate locally
bun test— full suite passes (dev),bun run test:prodpasses (prod).__tests__/core/type-system.test.tscover:prettyPrintDescriptionstability block that feeds adversarial input(empty, over-closed/never-closed braces, separators inside string literals,
trailing backslashes, multi-byte chars, deep nesting) and asserts it never
throws and never loses a non-whitespace character.