One error struct, reused across every stage -- Lexer, Parser, analysis
pass, and Ichor.Actions -- so errors look the same regardless of
origin.
It is an exception, though Ichor returns it rather than raising it: a
caller can raise an error it was handed, and Exception.message/1
gives the same text as format/1.
context_lines is pre-rendered at construction time, not lazily
computed on access: cheap to do once, and keeps every stage's error
output visually consistent.
data is whatever a stage wants to hand through with its error --
most often an action failing with its own domain error, wrapped here
so the parser's result stays an Ichor.Error and its caller unwraps
it. Ichor itself never sets or reads it, and format/1 ignores it.
Summary
Functions
Renders the full human-readable error: location, message, and the caret-annotated snippet, in that order.
The error as format/1 writes it, with where it is and the line it
points at: what Exception.message/1 gives, and what raise shows.
Builds a Ichor.Error, pre-rendering context_lines immediately.
Types
@type stage() :: :lexer | :parser | :analysis | :action
@type t() :: %Ichor.Error{ __exception__: true, column: pos_integer() | nil, context_lines: String.t() | nil, data: term(), expected: term(), file: String.t() | nil, found: term(), line: pos_integer() | nil, message: String.t(), stage: stage() | nil }
Functions
Renders the full human-readable error: location, message, and the caret-annotated snippet, in that order.
Examples
iex> error = Ichor.Error.new(
...> message: "expected ')'",
...> stage: :parser,
...> file: "calc.aether",
...> line: 1,
...> column: 8,
...> source: "(2 + 3"
...> )
iex> Ichor.Error.format(error)
"calc.aether:1:8: expected ')'\n1 | (2 + 3\n | ^"
The error as format/1 writes it, with where it is and the line it
points at: what Exception.message/1 gives, and what raise shows.
Builds a Ichor.Error, pre-rendering context_lines immediately.
Accepts :message (required), :stage, :line, :column, :file,
:expected, :found, :data, and either :source (the full source text, used
to render a caret-annotated snippet at :line/:column) or a
pre-rendered :context_lines directly, for callers that already have
one (e.g. re-wrapping an error from another stage).
Examples
iex> error = Ichor.Error.new(
...> message: "expected ')'",
...> stage: :parser,
...> line: 1,
...> column: 8,
...> expected: ")",
...> found: :eof,
...> source: "(2 + 3"
...> )
iex> error.context_lines
"1 | (2 + 3\n | ^"
iex> Ichor.Error.new(message: "boom", source: nil, line: nil).context_lines
nil