Skip to content

refactor: structured diagnostics; one validation path; no console output - #82

Merged
jstet merged 1 commit into
mainfrom
refactor/63-diagnostics
Sep 25, 2026
Merged

jstet merged 1 commit into
mainfrom
refactor/63-diagnostics

Conversation

@jstet

@jstet jstet commented Sep 25, 2026

Copy link
Copy Markdown
Member

Closes #63.

What changes

src/diagnostics.ts

Export Purpose
Diagnostic { code, severity, message, name? }, with a closed DiagnosticCode union (~40 codes)
ConversionError what every library function now throws: code, subject (the question), details (all findings when it summarises several), cause
WarningHandler, consoleWarning the default handler, and the only place the library writes to the console

SubsetViolation is now Diagnostic, so validateSubset findings also carry codes. This is additive.

One validation path. XLSValidator.rowDiagnostic() (types, choice lists) and appearanceDiagnostics() are what validateSubset collects, and what the converter throws or warns with. The converter's duplicates are deleted: validateRowType, assertChoiceList, assertFileChoices, UNIMPLEMENTED_TYPES, and its own appearance check. The converter doesn't run the full validateSubset, because that would add the LimeSurvey name gate to skipValidation conversions, which sanitize instead.

Warnings → onWarning:

  • LstsvConfig.onWarning
  • XLSLoader LoadOptions.onWarning
  • new FieldSanitizer(onWarning), new TypeMapper(onWarning)
  • convertConstraint(expr, onWarning)

All default to consoleWarning, so current behaviour is kept. Two specific changes:

  • A dropped constraint is now a constraint-dropped warning; before, it was a bare console.error.
  • The "Removed other choice" console.log is gone: that's the normal collapse, not a finding.

Errors: every throw reachable from the package root is a ConversionError with a code. XPathSyntaxError subclasses it (xpath-syntax).

Compatibility

  • Additive API. The converter's error message text changed (it now uses the validator's wording), so tests assert code now. Consumers that match messages should switch to codes.
  • TSV output unchanged (re-blessed, byte-identical).

Tests

tests/ts/unit/diagnostics.test.ts:

  • the converter reports through onWarning, and not the console
  • the sanitizer handler works
  • seven throw sites produce the expected codes
  • subject names the question
  • a guard: no console.* outside diagnostics.ts and the CLI

Results: vitest 898 passed. npm run validate is clean. pytest: 37 passed.

README gets an "Errors and warnings" section.

🤖 Generated with Claude Code

Two validation paths reported differently, library warnings went straight
to console.warn (invisible in the browser app), and ~40 plain Errors carried
no machine-readable code.

- src/diagnostics.ts: Diagnostic { code, severity, message, name? } with a
  closed DiagnosticCode union; ConversionError (code, subject, details,
  cause); WarningHandler and consoleWarning, the one place the library
  writes to the console. SubsetViolation is now Diagnostic, so
  validateSubset findings carry a code too.
- One row check: XLSValidator.rowDiagnostic() (type, choice lists) and
  appearanceDiagnostics() are what validateSubset collects and what the
  converter throws or warns with. The converter's own copies
  (validateRowType, assertChoiceList, assertFileChoices, UNIMPLEMENTED_TYPES,
  the appearance check) are gone, so its messages are the validator's.
- Warnings go to onWarning: LstsvConfig.onWarning, XLSLoader's
  LoadOptions.onWarning, the FieldSanitizer/TypeMapper constructors and
  convertConstraint. They default to consoleWarning. A dropped constraint is
  now a `constraint-dropped` warning instead of console.error. The "Removed
  other choice" console.log is gone.
- Every error the library throws is a ConversionError with a code;
  XPathSyntaxError subclasses it (code xpath-syntax).

Public API is additive; the message text of converter errors changed (tests
now assert codes). No console.* remains outside diagnostics.ts and the CLI,
which a test enforces. TSV output unchanged.

Closes #63

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@jstet
jstet merged commit 13a4aa8 into main Sep 25, 2026
4 checks passed
@jstet
jstet deleted the refactor/63-diagnostics branch September 25, 2026 15:12
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.

refactor: unify validation and replace console.warn / string errors with structured diagnostics

1 participant