Skip to content

Fix panic line number and instruction parsing#103

Closed
Oleg-Melnik wants to merge 4 commits into
masterfrom
panic-line-number
Closed

Fix panic line number and instruction parsing#103
Oleg-Melnik wants to merge 4 commits into
masterfrom
panic-line-number

Conversation

@Oleg-Melnik

Copy link
Copy Markdown
Collaborator

Summary

Fixes #19. The issue surfaced as a confusing panic/error while embedding into a real docs file:

failed to embed code fragment into doc file `file:///.../runtime-library.md:76`: failed to parse an embedding instruction ...

Investigation showed three distinct problems behind that one report, all fixed here:

  1. Instruction patterns containing XML metacharacters could not be parsed (root cause of the parse failure).
  2. A single malformed instruction consumed the rest of the document to EOF, making the error location misleading (an instruction on line 76 blew up at line 404).
  3. The error's file URL was not IDE-navigable — wrapped in backticks and missing a column component — which is the literal request in the issue title.

Changes

1. Escape XML metacharacters in attribute values (embedding/parsing/xml_parse.go)

quoteEscapedXMLLine previously escaped only \". Raw &, <, > inside an attribute value — routine in source-line patterns such as line="if (a < b)", start="List<String>", or end="while (x && y)" — made xml.Unmarshal reject the whole instruction.

It now walks the instruction, tracks whether it is inside a quoted attribute value, and escapes &/</> only within values, leaving the <embed-code header and /> terminator untouched. The & escaping is entity-aware: a pre-existing entity like &quot; (or a numeric reference such as &#39;) is preserved rather than double-escaped into &amp;quot;.

2. Bound the instruction-accumulation loop (embedding/parsing/instruction_token.go)

EmbedInstructionTokenState.Accept accumulates lines until an instruction parses or EOF. When a complete but invalid instruction failed to parse, it kept scanning to EOF, swallowing the code fence and everything after it.

Accept now stops once the tag is syntactically closed. The shared instructionClosed helper (also used by parseFailureReason) recognizes the /> and </embed-code> terminators only outside quoted attribute values, so a value such as line="<br/>" in a multiline instruction is not mistaken for the closing />.

3. Emit an IDE-navigable failure location (embedding/error.go, logging/logger.go)

  • New logging.FileReferenceWithPosition(path, line, column) produces the file://...:line:column form that IntelliJ IDEA recognizes for navigation.
  • ProcessingError.Error() drops the surrounding backticks and includes the column. Because the parser tracks line granularity only, the column is a documented constant 1 (start of the offending line).

Error message before / after:

- ... doc file `file:///.../doc.md:3`: failed to parse ...
+ ... doc file file:///.../doc.md:3:1: failed to parse ...

Tests

  • xml_parse / state_test: patterns with raw <, &, > now parse and embed correctly.
  • state_test: three specs asserting a malformed self-closed instruction (invalid glob, invalid comments mode, mutually-exclusive attributes) reports the error without consuming past the instruction line.
  • state_test: a multiline instruction with line="<br/>" parses successfully (guards the quote-aware terminator).
  • embedding_test: ProcessingError.Error() is a bare file://...:line:column URL with no backticks.
  • Updated four existing specs that were pinned to the old backtick format.

Full suite (go test ./...) and go vet ./... pass.

@Oleg-Melnik Oleg-Melnik changed the title Fix panic line number and instruction parsing (#19) Fix panic line number and instruction parsing Jul 7, 2026
Refactor to satisfy the CI linter:
- Reduce cyclomatic complexity of quoteEscapedXMLLine by extracting
  isEscapedQuote and escapeValueByte helpers (cyclop).
- Replace the magic number in xmlEntityPrefix with explicit
  empty-name handling (mnd).
- Rename short loop variable `i` to `index` in the byte scanners
  (varnamelen), and share isEscapedQuote with instructionClosed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Oleg-Melnik Oleg-Melnik self-assigned this Jul 7, 2026

@Vladyslav-Kuksiuk Vladyslav-Kuksiuk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@Oleg-Melnik, I don't think the issue this PR resolves still exists, because the same error message described in the issue can no longer be reproduced in the current version of the application.

Links in IntelliJ IDEA are clickable, even without the column number and even when they are surrounded by backticks.

Example: Image

I suggest closing this PR and leaving a comment on the issue explaining that it can no longer be reproduced.

Expect(errors.As(err, &parseErr)).Should(BeTrue())
})

// Regresses https://github.com/SpineEventEngine/embed-code-go/issues/19.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We should not mention resolved (after we merge this PR) issues in the doc.

Same in all other places.

Comment on lines +148 to +150
// The failure location must be a bare `file://...:line:column` URL so an
// IDE such as IntelliJ IDEA can open it from the console. Backticks around
// the URL and a missing column component prevent that navigation.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Backticks don’t prevent the link from being clickable in IntelliJ IDEA. Let’s keep them, as they are necessary to visually separate the link from the default text.

Example:

Image

Comment thread embedding/error.go
Comment on lines +47 to +50
// errorLocationColumn is the column reported for a processing failure. The
// parser tracks line granularity only, so the location points at the beginning
// of the offending line.
const errorLocationColumn = 1

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think that we need to show column number, as it's always hardcoded to 1.

I'm sure that link would be clickable even without column number.

@Oleg-Melnik Oleg-Melnik closed this Jul 8, 2026
@Oleg-Melnik

Copy link
Copy Markdown
Collaborator Author

Closed as cannot be reproduced on the latest version of the sources. The branch will remain alive for some time so it can be reopened if the issue is reproduced.

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.

URL of a file with error must contain line number

2 participants