Skip to content

Fix: Update parseSyntaxError to use lossless-json for accurate error locations - #181

Open
sameerakhtar406 wants to merge 5 commits into
codercops:developfrom
sameerakhtar406:fix/issue-#163-JSON-formatter
Open

sameerakhtar406 wants to merge 5 commits into
codercops:developfrom
sameerakhtar406:fix/issue-#163-JSON-formatter

Conversation

@sameerakhtar406

@sameerakhtar406 sameerakhtar406 commented Oct 15, 2026 •

Copy link
Copy Markdown

Closes #163

How I tested this:

Added Vitest test cases in lib/tests/json-utils.test.ts to cover the exact edge cases and multi-line formatting specified in the issue.
Ran npm run test and verified all 242 tests pass green.
Ran npm run lint and npm run build to ensure no regressions.
Booted the local dev server using npm run dev verified the UI correctly renders "line 1, column 7" for {"a": x} (screenshot attached) and all the other test cases mentioned in Issue #163

7215f899-eece-41f3-9732-0f26b5c6ab9e

AI assistance:

Used LLMs to help structure the TypeScript try...catch fallback logic, navigate strict type narrowing for unknown errors and be sure of my work

@anurag629 anurag629 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @sameerakhtar406, the lossless-json fallback works. All four inputs from the table now show the right line and column, and the screenshot is there. A few things before it can go in:

  1. Please keep the first two branches as they were (if (posMatch) and else if (lineMatch)) and only add the lossless-json part as the final else. Chrome and Node put both in the same message ("at position 13 (line 1 column 14)"), so with the new conditions every message that already has a location goes to lossless-json too. That breaks one case: lossless-json stops at a duplicate key, so {"a":1,"a":2,} shows line 1, column 9 with this PR, while develop correctly shows column 14 (the trailing comma). Can you add that as a test?
  2. The multi-line test uses a different input from the issue. The table's second row is three lines, {"a": 1, then "b": tru then }, so '{"a": 1,\n"b": tru\n}' with line 2, column 6 (your code already gets that one right). Please drop the "Adjust column" comment with it.
  3. Small cleanup: remove the commented //let message; and the extra blank lines, fix the indentation of the closing braces, and add validate to the import list at the top of the test file instead of a second import further down.

The red "Says how it was tested" check is only about the format. It looks for the section names as headings, so put ## in front of "How I tested this" and "AI assistance" and it turns green. What you wrote in them is fine.

@sameerakhtar406

Copy link
Copy Markdown
Author

Sure @anurag629, I'll just fix these right away

@sameerakhtar406

Copy link
Copy Markdown
Author

Hi @anurag629, I've fixed a sometime back, kindly check :)

@anurag629 anurag629 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @sameerakhtar406, the logic is right now. I checked it: the four inputs from the issue give the right line and column, {"a":1,"a":2,} stays at column 14, {"a":1,} stays at column 8, and the four new tests fail with develop's json-utils.ts like they should. Lint and all 243 tests pass.

Only the formatting from point 3 is left. A few lines have trailing spaces, the else/try/catch aren't formatted like the rest of the file, and the function's closing brace ended up indented. I put the fixed lines as suggestions below, so you can commit them from this page ("Add suggestion to batch" on each one, then "Commit suggestions"). I'll merge once CI is green after that.

Comment thread lib/json-utils.ts
Comment thread lib/json-utils.ts Outdated
Comment on lines +51 to +72
}
else{
try{
llParse(raw);
}
catch(llError) {
if (llError instanceof Error) {
const llPosMatch = llError.message.match(/position (\d+)/i);
if (llPosMatch) {
position = parseInt(llPosMatch[1], 10);
const lc = computeLineCol(raw, position);
line = lc.line;
column = lc.column;
}
}
}
}

const suggestion = suggestFix(raw);
return { message: msg.replace(/in JSON.*$/, "").trim() || "Invalid JSON", line, column, position, suggestion };
}

}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
else{
try{
llParse(raw);
}
catch(llError) {
if (llError instanceof Error) {
const llPosMatch = llError.message.match(/position (\d+)/i);
if (llPosMatch) {
position = parseInt(llPosMatch[1], 10);
const lc = computeLineCol(raw, position);
line = lc.line;
column = lc.column;
}
}
}
}
const suggestion = suggestFix(raw);
return { message: msg.replace(/in JSON.*$/, "").trim() || "Invalid JSON", line, column, position, suggestion };
}
}
} else {
try {
llParse(raw);
} catch (llError) {
if (llError instanceof Error) {
const llPosMatch = llError.message.match(/position (\d+)/i);
if (llPosMatch) {
position = parseInt(llPosMatch[1], 10);
const lc = computeLineCol(raw, position);
line = lc.line;
column = lc.column;
}
}
}
}
const suggestion = suggestFix(raw);
return { message: msg.replace(/in JSON.*$/, "").trim() || "Invalid JSON", line, column, position, suggestion };
}

Comment thread lib/__tests__/json-utils.test.ts Outdated
sameerakhtar406 and others added 2 commits October 17, 2026 10:25
Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
@sameerakhtar406

Copy link
Copy Markdown
Author

Thanks @anurag629, I think I have applied all the batched formatting suggestions! Ready for the CI approval whenever you get a moment

@anurag629 anurag629 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @sameerakhtar406, two of the three went in. The one for the else/try/catch block didn't make it, GitHub sometimes marks a suggestion as outdated once another one moves the lines. Here it is again for the current lines, so it's one more click. I'll merge after that.

Comment thread lib/json-utils.ts Outdated
Comment on lines +49 to +70
}
else{
try{
llParse(raw);
}
catch(llError) {
if (llError instanceof Error) {
const llPosMatch = llError.message.match(/position (\d+)/i);
if (llPosMatch) {
position = parseInt(llPosMatch[1], 10);
const lc = computeLineCol(raw, position);
line = lc.line;
column = lc.column;
}
}
}
}

const suggestion = suggestFix(raw);
return { message: msg.replace(/in JSON.*$/, "").trim() || "Invalid JSON", line, column, position, suggestion };
}

}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
else{
try{
llParse(raw);
}
catch(llError) {
if (llError instanceof Error) {
const llPosMatch = llError.message.match(/position (\d+)/i);
if (llPosMatch) {
position = parseInt(llPosMatch[1], 10);
const lc = computeLineCol(raw, position);
line = lc.line;
column = lc.column;
}
}
}
}
const suggestion = suggestFix(raw);
return { message: msg.replace(/in JSON.*$/, "").trim() || "Invalid JSON", line, column, position, suggestion };
}
}
} else {
try {
llParse(raw);
} catch (llError) {
if (llError instanceof Error) {
const llPosMatch = llError.message.match(/position (\d+)/i);
if (llPosMatch) {
position = parseInt(llPosMatch[1], 10);
const lc = computeLineCol(raw, position);
line = lc.line;
column = lc.column;
}
}
}
}
const suggestion = suggestFix(raw);
return { message: msg.replace(/in JSON.*$/, "").trim() || "Invalid JSON", line, column, position, suggestion };
}

@sameerakhtar406

Copy link
Copy Markdown
Author

Hey @anurag629 , GitHub was giving an error applying the inline suggestion as I think it lost track of line numbers after earlier commits due to shifted lines, so I fixed it locally in VS Code and pushed it. I hope it will work now. Let me know if there's still any issue :)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JSON formatter points at line 1, column 1 for most errors in Chrome

2 participants