Skip to content

[codex] Improve UndefinedError diagnostics for framework views#132

Merged
lbliii merged 7 commits into
mainfrom
codex/structured-error-diagnostics
May 22, 2026
Merged

[codex] Improve UndefinedError diagnostics for framework views#132
lbliii merged 7 commits into
mainfrom
codex/structured-error-diagnostics

Conversation

@lbliii
Copy link
Copy Markdown
Owner

@lbliii lbliii commented May 18, 2026

Summary

Adds a structured UndefinedError diagnostic payload that framework debug views can consume without parsing terminal strings, plus escaped HTML/Markdown renderers for the same diagnostic data.

Changes

  • Add UndefinedError.to_diagnostic() with code, kind, location, source snippet, ordered hints, docs URL, metadata, template stack, and component stack.
  • Add escaped diagnostic renderers for HTML fragments, standalone HTML pages, and Markdown.
  • Preserve attribution for coalesced output, imported macro caller slots, imported component stack frames, attribute/key misses, and streaming generic runtime errors.
  • Update framework/error-handling docs for structured diagnostics and source stack interpretation.

Steward Notes

Consulted runtime, template runtime, render-surface, tests, and docs stewards. Accepted findings centered on diagnostic truth before UI polish, surface-neutral data, escaped final renderers, render-mode parity, and docs/test collateral. Deferred public frame API, column-accurate carets, Python traceback remapping, and exposing context values.

Verification

  • PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 uv run pytest tests/test_diagnostics_contract.py tests/test_error_stack_traces.py tests/test_undefined_nullsafe_hint.py tests/test_kida_error_handling.py::TestFormatCompact
  • make docs
  • make lint
  • make ty

@lbliii lbliii marked this pull request as ready for review May 22, 2026 12:33
Copilot AI review requested due to automatic review settings May 22, 2026 12:33
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a structured, surface-neutral diagnostic payload for UndefinedError so framework debug views can render rich error pages without parsing terminal-formatted strings, alongside escaped HTML/Markdown renderers and improved attribution for imported components/slots and coalesced output.

Changes:

  • Introduces UndefinedError.to_diagnostic() + new TemplateDiagnostic datatypes with HTML fragment/page and Markdown renderers.
  • Improves error attribution by carrying template/component stack context and preserving source line markers under f-string coalescing.
  • Enhances streaming render paths to wrap generic runtime exceptions consistently with non-streaming render.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/test_diagnostics_contract.py Adds contract tests for structured diagnostics, escaping, stack attribution, and streaming error enhancement.
src/kida/template/render_helpers.py Tracks imported macro call-site separately to preserve component stack caller attribution.
src/kida/template/helpers.py Enriches UndefinedError for attribute/key misses with stacks, declared definitions, and fuzzy suggestions.
src/kida/template/core.py Enables/enhances error wrapping for render_stream and async block streaming to match render() behavior.
src/kida/render_context.py Extends RenderContext with component_call_* to support imported macro call-site overrides.
src/kida/exceptions.py Adds structured diagnostic dataclasses and renderers; refactors UndefinedError to expose structured fields and hints.
src/kida/compiler/statements/functions.py Updates component stack push logic to use call-site overrides; adjusts call-block wrapper attribution behavior.
src/kida/compiler/coalescing.py Preserves first output line marker when emitting coalesced f-string output for correct diagnostics.
site/content/docs/usage/framework-integration.md Documents how frameworks should render structured diagnostics instead of parsing terminal output.
site/content/docs/usage/error-handling.md Updates guidance to prefer to_diagnostic() for framework debug pages; clarifies source/stack interpretation.
site/content/docs/troubleshooting/undefined-variable.md Documents new structured fields and imported-slot attribution behavior; clarifies hint ordering.

Comment thread src/kida/exceptions.py
Comment on lines +522 to +530
if self.source_snippet:
parts.extend(["", "```text"])
for lineno, content in self.source_snippet.lines:
marker = ">" if lineno == self.source_snippet.error_line else " "
parts.append(f"{marker}{lineno:4} | {content}")
if self.source_snippet.column is not None:
caret = " " * self.source_snippet.column + "^"
parts.append(f" | {caret}")
parts.append("```")
Comment on lines +693 to +761
wrapper_body: list[ast.stmt] = [
ast.Assign(
targets=[ast.Name(id="_rc", ctx=ast.Store())],
value=ast.BoolOp(
op=ast.Or(),
values=[
ast.Call(
func=ast.Name(id="_get_render_ctx", ctx=ast.Load()),
args=[],
keywords=[],
),
ast.Name(id="_null_rc", ctx=ast.Load()),
],
),
),
ast.Assign(
targets=[ast.Name(id="_prev_template_name", ctx=ast.Store())],
value=ast.Attribute(
value=ast.Name(id="_rc", ctx=ast.Load()),
attr="template_name",
ctx=ast.Load(),
),
),
ast.Assign(
targets=[ast.Name(id="_prev_source", ctx=ast.Store())],
value=ast.Attribute(
value=ast.Name(id="_rc", ctx=ast.Load()),
attr="source",
ctx=ast.Load(),
),
),
ast.Assign(
targets=[ast.Name(id="_prev_line", ctx=ast.Store())],
value=ast.Attribute(
value=ast.Name(id="_rc", ctx=ast.Load()),
attr="line",
ctx=ast.Load(),
),
),
ast.Assign(
targets=[
ast.Attribute(
value=ast.Name(id="_rc", ctx=ast.Load()),
attr="template_name",
ctx=ast.Store(),
)
],
value=ast.Name(id="_caller_template_name", ctx=ast.Load()),
),
ast.Assign(
targets=[
ast.Attribute(
value=ast.Name(id="_rc", ctx=ast.Load()),
attr="source",
ctx=ast.Store(),
)
],
value=ast.Name(id="_caller_source", ctx=ast.Load()),
),
ast.Assign(
targets=[
ast.Attribute(
value=ast.Name(id="_rc", ctx=ast.Load()),
attr="line",
ctx=ast.Store(),
)
],
value=ast.Name(id="_caller_line", ctx=ast.Load()),
),
@lbliii lbliii merged commit 66cf8ec into main May 22, 2026
10 checks passed
@lbliii lbliii deleted the codex/structured-error-diagnostics branch May 22, 2026 12:46
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