diagnostics
Defines best practices for error reporting, mandating actionable and structured diagnostics over panic-based failures.
Install
mkdir -p .claude/skills/diagnostics && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/16628" && unzip -o skill.zip -d .claude/skills/diagnostics && rm skill.zipInstalls to .claude/skills/diagnostics
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Error handling and build-time diagnostics conventions - Result-not-panic, structured Diagnostics with stable codes, actionable help, color/JSON presentation layering, exit codes, and cold-path performance.Key capabilities
- →Return `Result` for recoverable errors
- →Create structured `Diagnostic` for authoring errors
- →Provide actionable `help:` lines
- →Suggest closest matches for typos
- →Present plain, color-free data from libraries
- →Classify exit codes for CLI errors
How it works
The skill enforces returning `Result` for recoverable errors and generates structured `Diagnostic` objects with stable codes and actionable help messages.
Inputs & outputs
When to use diagnostics
- →Refactor panic! to return Result
- →Create structured CLI validation errors
- →Implement recoverable error paths in web UI
- →Add helpful diagnostics to build tools
About this skill
Error Handling & Diagnostics
Use this skill whenever you add, change, or review an error path: a build-time authoring error, a parser/handler failure, a CLI validation error, or anything surfaced to a host (FFI/WASM/Node) or a tool/agent. WebUI errors must be recoverable, actionable, and machine-consumable — for humans and AI agents alike.
1 - Never panic on recoverable input
panic = "abort" in the release profile means a panic kills the process
instantly — including any FFI/WASM/Node host embedding the framework. Bad
template input, bad CLI input, and bad state are recoverable and must return
Result, never panic!/unwrap()/expect().
| Situation | Do |
|---|---|
| Malformed template / CSS / route authored by a developer | Return Result with a structured Diagnostic (see §3). |
| Missing/invalid CLI input (file, port, flag) | Return a typed CliError (see §6). |
| A genuinely impossible internal state | Prefer ? with a typed error; only use unreachable!/expect with a justification comment, and never in a hot or host-reachable path. |
unwrap()/expect() are banned in library code (clippy.toml
disallowed-methods). todo!, unimplemented!, and dbg! are banned
workspace-wide (clippy.toml disallowed-macros). Tests opt out with
#[allow(clippy::disallowed_methods)].
Enforcement note.
unwrap/expect/todo!/unimplemented!/dbg!are caught by clippy.panic!is not lint-banned (too entrenched) — keep it out of recoverable paths by review. The "no regex in core logic" rule is also review-enforced, notdeny-banned:actix-webpullsregextransitively, so a crate-level ban would break the build and can't scope to first-party code.
2 - Error type conventions
| Crate kind | Error type |
|---|---|
Library (webui-parser, webui-handler, webui-expressions, webui-state, webui-protocol, webui-ffi) | Custom enum via thiserror. |
Binary (webui-cli, xtask) | anyhow for orchestration; a typed enum when callers must branch on the cause (e.g. webui-cli's CliError for hints + exit codes). |
- Each error layer's
Displaydescribes only its own level; the#[source]chain carries the rest, soanyhow's{:#}never double-prints. Provide a flatchain_message()helper for hosts that don't walk the chain (Node, FFI). - Add dedicated variants instead of overloading a generic
Generic(String)/Validation(String)so callers canmatchprogrammatically.
3 - Authoring errors are structured Diagnostics
Every "the developer wrote invalid template syntax" mistake is returned as
ParserError::Template(Box<Diagnostic>) (crates/webui-parser/src/diagnostic.rs),
so all build errors render identically. A Diagnostic carries:
code— a stable, machine-readable identifier (e.g.invalid-for-each). Defined indiagnostic::codes. Treat codes as a stable API: tools and AI agents branch on them, so rename only with a deliberate migration.- title — short, lowercase (
invalid <for> each expression). - location — set from a byte offset via
.at_offset(source, offset); rendered rustc-style--> owner:line:column(single forward scan, no regex, no recursion), falling back toin component <c> · element <e>. - snippet — the offending source text.
help:— an actionable fix (see §4).
Add a new authoring error with the parser helpers (authoring_error,
authoring_error_at, html_error) and a new constant in diagnostic::codes.
Validate at parse/build time and fail fast — never defer to render time.
4 - Make errors actionable (and typo-aware)
Tell the developer what is wrong and how to fix it. Every Diagnostic
should carry a help: line. Where a mistake is likely a typo, suggest the
intended name via suggest::closest_match (iterative Levenshtein — no
recursion, no regex, cold path only):
- Misspelled directive attribute:
<for eahc=…>-> "did you meaneach?" - Unknown component tag: suggest the closest same-namespace registered
component (
<mp-buton>-><mp-button>). Prefix-guard the match (text before the first-must match) so a genuine third-party custom element (<md-button>) is never falsely flagged.
5 - Presentation layering: color belongs ONLY in the entry point
Libraries produce plain, color-free data. The entry point decides how to present it. Never embed ANSI in library output or in any machine/host channel.
| Consumer | Gets |
|---|---|
webui-cli (terminal) | Reads Diagnostic fields and colorizes with console::style() — the only approved styling method (see copilot-instructions "Terminal output styling"). |
| FFI / WASM / Node | The plain Display text through their native error channel (webui_last_error, JsValue, napi::Error). |
Browser / tools (dev-server live-reload, SSE, console.error) | Plain text. ANSI renders as garbage and breaks single-line SSE frames. |
When one value feeds both a terminal and a non-terminal channel, split it:
webui-dev-server's RebuildError { display, message } carries a colorized
display for the reporter and a plain message for the browser.
Per-line color: when colorizing multi-line output, style each line
independently (open + close the SGR span within the line). A single span that
straddles newlines bleeds when the line is later re-prefixed (e.g. [server]
under xtask dev).
6 - Machine-readable output and exit codes (webui-cli)
For editors, CI, and AI/agent tooling:
--format json(global flag) emits each error as one JSON object on stdout (no ANSI; decorative output suppressed):{severity, code, message, file, line, column, snippet, help, chain}. Branch on the stablecode, not the humanmessage. Build the object with theserde_json::MapAPI, not thejson!macro (itunwraps internally and tripsdisallowed_methods).- Exit codes follow BSD
sysexits.h(webui-cli'serror::exit_code):65data/authoring error,66missing input,69port in use,74I/O,2usage (clap),1otherwise. - Replace fragile
err_msg.contains("...")dispatch with typed errors that own theirhint()andexit_code().
7 - Error construction is COLD - keep it off the hot path
Building a Diagnostic (format strings, suggestions, location scans) is rare,
but if it inlines into a hot function it bloats that function and perturbs its
code layout — a real, measurable regression (observed ~4-5% on parse benches
with no added hot-path work).
- Mark error builders
#[cold]+#[inline(never)](e.g.authoring_error*,html_error,css_diagnostic,*_errorconstructors,suggest::closest_match). - Keep hot fast-paths inlinable: a per-element check (e.g.
split_once('-')) must stay inlined; only its cold fallback (the registry scan) goes out-of-line. - Validate layout-sensitive changes with
cargo bench -p <crate>against the base branch (seeskills/perf/SKILL.md). A "regression" with no added compute is usually layout — fix it with#[cold], don't shrug it off.
8 - Checklist for a new error
- Returned as
Result, never panicked (host-safe underpanic = "abort"). - Authoring mistake ->
ParserError::Template(Box<Diagnostic>)with a newdiagnostic::codesconstant, location, snippet, andhelp:. -
help:is actionable; add a "did you mean …?" suggestion if it's a typo. - No color/ANSI in library, host, browser, or JSON output.
- Surfaced in
--format jsonwith the stablecode; exit code classified. - Error construction is
#[cold]/#[inline(never)]; hot path unchanged (confirm with a benchmark if it sits near a hot loop). - Tests: a regression test that fails without the error, asserting on the
code(not the prose); JSON stays plain (no\x1b). -
DESIGN.mdanddocs/(incl.docs/ai/SKILL.md) updated if the contract or a user-visible code/flag changed.
When not to use it
- →When a panic is genuinely for an impossible internal state that cannot be recovered
- →When the error path is not a build-time authoring error, parser/handler failure, or CLI validation error
Limitations
- →The skill focuses on error handling and build-time diagnostics conventions
- →The skill's `panic!` linting is review-enforced, not `deny`-banned
- →The skill's regex rule is review-enforced, not `deny`-banned
How it compares
This skill provides machine-consumable and actionable diagnostics with stable codes, unlike generic error messages that may lack context or guidance.
Compared to similar skills
diagnostics side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| diagnostics (this skill) | 0 | 2mo | Review | Intermediate |
| find-bugs | 5 | 7mo | No flags | Intermediate |
| supabase-common-errors | 4 | 1mo | Review | Intermediate |
| tech-debt-analyzer | 5 | 9mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by microsoft
View all by microsoft →You might also like
find-bugs
davila7
Find bugs, security vulnerabilities, and code quality issues in local branch changes. Use when asked to review changes, find bugs, security review, or audit code on the current branch.
supabase-common-errors
jeremylongshore
Execute diagnose and fix Supabase common errors and exceptions. Use when encountering Supabase errors, debugging failed requests, or troubleshooting integration issues. Trigger with phrases like "supabase error", "fix supabase", "supabase not working", "debug supabase".
tech-debt-analyzer
ailabs-393
This skill should be used when analyzing technical debt in a codebase, documenting code quality issues, creating technical debt registers, or assessing code maintainability. Use this for identifying code smells, architectural issues, dependency problems, missing documentation, security vulnerabilities, and creating comprehensive technical debt documentation.
static-analysis
gmh5225
Expertise in LLVM-based static analysis including dataflow analysis, pointer analysis, taint tracking, and program verification. Use this skill when implementing security scanners, bug finders, code quality tools, or performing program analysis research.
agent-code-analyzer
ruvnet
Agent skill for code-analyzer - invoke with $agent-code-analyzer
memory-safety-patterns
sickn33
Implement memory-safe programming with RAII, ownership, smart pointers, and resource management across Rust, C++, and C. Use when writing safe systems code, managing resources, or preventing memory bugs.