Diagnostic presentation
gargamelle/diagnostics formats existing ContractError values. It does not
validate JSON, decode values, run semantic checks, or invoke handlers.
import gargamelle
import gargamelle/diagnostics as gargamelle_diagnostics
import gleam/io
pub fn main() {
let contract = gargamelle.contract(gargamelle.array(gargamelle.text()))
let assert Ok(json) = gargamelle.parse("[\"Brainy\", false]")
let assert Error(error) = gargamelle.decode_contract(contract, json)
io.println(gargamelle_diagnostics.summary(error, 5))
let assert Ok(report) = gargamelle_diagnostics.to_json(error)
io.println(gargamelle.to_string(report, gargamelle.Compact))
}
Output:
"/1" ["string_type"]: Expected a string
{"errors":[{"branches":[],"category":"string_type","matches":[],"missing_key":null,"path":"/1"}],"kind":"structural"}
Bounded summaries
summary(error, max_details) produces readable text with at most the requested
number of detail lines and an additional omission marker when details were left
out. The limit is clamped to 0–100. Union branch expansion stops at depth eight;
each line is limited to 160 graphemes. Paths, categories, and application messages
are quoted with JSON escaping, preventing embedded line breaks from creating
additional lines. These limits affect presentation, not validation or its error
collection. The original structured error remains available to the caller.
Union alternatives and semantic requirement headings count toward the detail
budget. Indices are zero-based and retain declaration order. A zero limit returns
only an omission marker for nonempty errors; an empty error produces empty text.
Unknown categories retain their category with the explanation Constraint failed.
Categories and message wording may evolve before 1.0. Applications should inspect
structured fields rather than parse summary text.
Complete JSON reports
to_json(error) returns admitted JSON containing the complete diagnostic tree.
Structural reports contain kind: "structural" and an errors array; each error
retains its category, input JSON Pointer, optional missing key, matching alternative
indices, and indexed branch errors. Semantic reports contain kind: "semantic"
and a requirements array retaining indices, descriptions, and path/message
violations. The report does not invent schema locations or reference traces that
are absent from the original errors. It carries no acceptance certificate.
JSON reports are not truncated. Serializing large error trees has a cost proportional to their size; use a bounded summary for routine display and retain the original errors when complete serialization is unnecessary. Non-scalar strings in application-authored diagnostics return an admission error.
Neither format includes submitted JSON values automatically. Application-authored requirement descriptions and violation messages are included and may themselves contain sensitive data; the formatter does not redact them. Field names and paths can also contain sensitive identifiers. Applications decide which reports to retain or expose.
For structural decode errors, wrap the list with gargamelle.Structural(errors).
For gargamelle_encoding.Contract(error) failures, format the enclosed contract error.
Other encoding errors retain their typed reasons and output paths, described in
Typed JSON encoding. The
boundary guide describes semantic
rejection during loading and saving.