Skip to content

Point configuration errors at the exact line and make colour optional - #103

Merged
bgrewell merged 2 commits into
mainfrom
feature/precise-config-errors
Aug 8, 2026
Merged

Point configuration errors at the exact line and make colour optional#103
bgrewell merged 2 commits into
mainfrom
feature/precise-config-errors

Conversation

@bgrewell

@bgrewell bgrewell commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Modelled on CORE's manifest error rendering (grewelltech/core, mvp branch) — a located, colourised snippet that marks the line to change.

Option errors pointed at the wrong line

A typo in evaluatte: on line 11 marked line 6, the start of the test:

  > 6 |   - name: check the service
    7 |     node: local
    8 |     type: execute

DART already captured positions for each node/test/step block and for their type:/node: keys, but not for individual option keys. It now records those too, so the error marks the key itself:

     9 |     options:
    10 |       command: "true"
  > 11 |       evaluatte:
    12 |         exit_code: 0

ConfigError.Key — declared but unused until now — carries which option is at fault.

Syntax errors got no snippet at all

Error: yaml: line 2: did not find expected '-' indicator

The position was in the message text, and nothing rendered it. Any error carrying a YAML position is now converted to a located ConfigError on the way out of parsing:

Error: did not find expected '-' indicator

  suite.yaml

  ─────────────────────────────────────
    1 | suite: bad yaml
  > 2 | nodes:
    3 |   - name: local
  ─────────────────────────────────────

The conversion happens in one deferred choke point rather than at each yaml.Unmarshal — the first parse is inside substituteVars, so a per-call-site fix would have missed it. It is skipped once !!load_from has inlined other files, because the line numbers no longer match the file on disk and a snippet pointing at the wrong line is worse than none.

Colour is now optional

--color auto|always|never, defaulting to auto: colours when stdout is a terminal and honours NO_COLOR (the cross-tool convention). always forces it on for a pipe that renders ANSI; never turns it off.

It is resolved before anything can print, so an error rendered on the way out of parsing already honours the setting. An invalid value is rejected rather than silently treated as auto.

Verified: --color always emits escapes through a pipe, --color never and NO_COLOR=1 produce none.

What I did not take from CORE

CORE also separates a short Summary from a longer Detail and renders a column caret. DART's messages are already single-sentence and specific, and its SourceLocation.Column is populated but points at the YAML key rather than the offending token within it, so a caret would often be misleading. Left alone rather than added speculatively — happy to revisit if you want the two-part shape.

Verification

New tests cover position recovery from both YAML error shapes, that unlocated errors pass through untouched rather than acquiring a misleading location, that an already-located error keeps its own, and that an option key's recorded line differs from its block's. All example suites still pass --check; build, vet, gofmt, and the full suite are green; the docs site builds.

Modelled on CORE's manifest error rendering: a located, colourised snippet
that marks the line to change.

Option errors marked the first line of the enclosing test or step, so a typo
in `evaluatte:` on line 11 pointed at line 6. Option key positions are now
recorded alongside the block positions already captured, and an error about
an option marks that option's own key. The Key field on ConfigError, unused
until now, carries which one.

YAML syntax errors got no snippet at all — just `yaml: line 2: ...` with the
position buried in the message. Any error carrying a YAML position is now
converted to a located ConfigError on the way out of parsing, so a malformed
suite gets the same treatment a semantic error gets. The conversion is
skipped once load_from has inlined other files, since the line numbers no
longer correspond to the file on disk.

Colour is now controllable with --color: auto (the default, which colours
only when stdout is a terminal and honours NO_COLOR), always, or never. It is
resolved before anything can print, so an error rendered on the way out of
parsing already honours the setting.
The unknown-option case pointed at the option's own key, but a value error
such as timeout: -5 still marked the first line of the enclosing test or
step. Both now take the option name from the front of the message — the
convention every option error follows — and use that option's recorded
position when the block really has an option by that name, falling back to
the block otherwise.
@bgrewell
bgrewell merged commit 1f5ed6f into main Aug 8, 2026
2 checks passed
@bgrewell
bgrewell deleted the feature/precise-config-errors branch August 8, 2026 21:44
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.

1 participant