Skip to content

fix: show actual parse error for malformed XML instead of generic fallback#134

Open
kyuchia wants to merge 1 commit into
mainfrom
fix/validator-worker-loading
Open

fix: show actual parse error for malformed XML instead of generic fallback#134
kyuchia wants to merge 1 commit into
mainfrom
fix/validator-worker-loading

Conversation

@kyuchia
Copy link
Copy Markdown

@kyuchia kyuchia commented Apr 17, 2026

Previously, entering malformed XML in the mei column (e.g. </neume missing >) would show a generic "Failed to validate MEI" tooltip for every error. The actual xmllint error never reached the UI.

Root cause

validateMEI() inserts the user's MEI string into an XML document via layer.innerHTML = value. On malformed XML, this throws a SyntaxError which is silently caught, and the generic fallback message is returned. The validation worker is never invoked.

Fix

Added a DOMParser well-formedness check before the innerHTML insertion. Malformed XML is caught early and the actual parse error is shown in the tooltip. Well-formed XML continues through the existing worker + xmllint pipeline unchanged.

Before / After

Before: every malformed XML error shows the same generic message

invalid_test-Network_tab_filter-Worker

After: tooltip shows the actual parse error

after_malformed_tooltip_missing_bracket

Testing

  • Malformed XML (<neume> instead of </neume>) → tag mismatch error in tooltip
after_malformed_tooltip_typo
  • Sample: SQUAREnotation-NEUMElevel (39 rows) → INVALID with real xmllint errors
after_sample_square_xmllint_error

Related: #133

…lback

Use DOMParser to check XML well-formedness before innerHTML insertion.
Related: #133
@kyuchia kyuchia requested a review from yinanazhou April 24, 2026 14:00
Comment on lines +90 to +97
// Check if user's MEI input is well-formed XML before inserting
const wrappedValue = `<root>${value}</root>`;
const userDoc = parser.parseFromString(wrappedValue, 'text/xml');
const parseError = userDoc.querySelector('parsererror');
if (parseError) {
resolve([parseError.textContent || 'Malformed XML']);
return;
}
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.

This feels redundant. We are only validating small chunks of MEI. Making L126 more specific, like indicating it's syntax error, should be enough.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for the review. I tested e.message from the innerHTML SyntaxError, it always gives the same generic message regardless of the error type:

// All three produce the exact same e.message:
try { layer.innerHTML = '<neume><nc tilt="e"/></neume'; } catch (e) { console.log(e.message); }
try { layer.innerHTML = '<neume><nc tilt="e"/></neme>'; } catch (e) { console.log(e.message); }
try { layer.innerHTML = '<neume><nc tilt="e"/><neume>'; } catch (e) { console.log(e.message); }
// "Failed to set the 'innerHTML' property on 'Element': The provided markup is invalid XML..."

So the catch block alone can't provide specific errors, which is why I added the DOMParser check before the innerHTML call. I used DOMParser because the tooltip is the only feedback users get, and I thought showing the actual parse error (like 'tag mismatch at line 3') would help users fix their input faster.

Happy to simplify if that's too much detail.

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.

2 participants