diff --git a/TODOS.md b/TODOS.md index e5edb13..68dd36d 100644 --- a/TODOS.md +++ b/TODOS.md @@ -2,6 +2,7 @@ - Polish existing features before moving on to new ones. - [ ] Improve diagnostics + - [ ] keep track of every error and don't report them more than once. - [ ] All Diagnostics should show: - [ ] *What* went wrong - [ ] *where* (in the file) diff --git a/menus.odin b/menus.odin index 4b19eea..d102795 100644 --- a/menus.odin +++ b/menus.odin @@ -393,4 +393,3 @@ parse_config_menus :: proc( return result } - diff --git a/mustache/diagnostic.odin b/mustache/diagnostic.odin index 59a7c82..43e629d 100644 --- a/mustache/diagnostic.odin +++ b/mustache/diagnostic.odin @@ -309,14 +309,18 @@ write_gutter :: proc(sb: ^strings.Builder, width: int, faint: string, reset: str // format_render_error produces a diagnostic for an Error value using the // template's path and source for context. Returns "" for nil errors. +// If the error carries its own source/path (from tag_error), those are used +// instead of the passed-in template — this ensures errors inside partials +// point at the correct file. format_render_error :: proc(err: Error, tmpl: Template, colorize: bool = false) -> string { if err == nil { return "" } - path := tmpl.path + b := body(err) + source := b.source != "" ? b.source : tmpl.source + path := b.path != "" ? b.path : tmpl.path if path == "" { path = "" } - b := body(err) - return format_error(path, tmpl.source, b.pos, b.msg, colorize = colorize) + return format_error(path, source, b.pos, b.msg, colorize = colorize) } diff --git a/mustache/mustache.odin b/mustache/mustache.odin index 9165872..bf3783a 100644 --- a/mustache/mustache.odin +++ b/mustache/mustache.odin @@ -26,9 +26,11 @@ Error_Kind :: enum { } Error_Body :: struct { - msg: string, - pos: int, - kind: Error_Kind, + msg: string, + pos: int, + kind: Error_Kind, + source: string, + path: string, } // Error is nil when no error occurred. @@ -47,6 +49,20 @@ body :: proc(err: Error) -> Error_Body { } } +// tag_error stamps an Error with the source/path of the template where it +// originated, so diagnostics point at the correct file (e.g. a partial). +tag_error :: proc(err: Error, tmpl: Template) -> Error { + if err == nil do return nil + b := body(err) + return Error_Body { + msg = b.msg, + pos = b.pos, + kind = b.kind, + source = tmpl.source, + path = tmpl.path, + } +} + // --------------------------------------------------------------------------- // Node tree // --------------------------------------------------------------------------- @@ -585,7 +601,7 @@ render_nodes :: proc( if len(node.filters) > 0 { transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:]) if perr != nil { - return perr + return tag_error(perr, current) } val = transformed } @@ -627,7 +643,7 @@ render_nodes :: proc( if len(node.filters) > 0 { transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:]) if perr != nil { - return perr + return tag_error(perr, current) } val = transformed } @@ -665,7 +681,7 @@ render_nodes :: proc( if len(node.filters) > 0 { transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:]) if perr != nil { - return perr + return tag_error(perr, current) } val = transformed } @@ -729,7 +745,7 @@ render_nodes :: proc( if len(node.filters) > 0 { transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:]) if perr != nil { - return perr + return tag_error(perr, current) } val = transformed }