# `Md.Parser.Error`
[🔗](https://github.com/am-kantox/md/blob/v0.15.1/lib/md/parser/error.ex#L1)

Diagnostic reporting for an input the generated parser has no clause for.

`Md.Engine` compiles the syntax map into a `do_parse/2` clause set. Every
clause is emitted from a syntax declaration, so the set is *closed*: an input
that reaches the catch-all clause has found a gap in the syntax definition
(or a bug in the engine), not merely an unusual document.

This module turns the parser state at that moment into something a maintainer
can act on. It reports, via `Logger.error/1`:

  * the offending continuation, with its byte size and a `byte_size`-aware
    preview (so a multi-byte character is never split);
  * the full mode stack, top first -- the mode is what selects the clause, so
    it is the single most useful piece of context;
  * the open path (the elements currently being built) and the pending
    `bag` contents;
  * a hint derived from the top mode and the leading bytes, naming the
    construct whose clause is missing.

It then raises `Md.Parser.Error` with the same information in the message, so
the failure is visible to the consumer and not only in the log.

# `t`

```elixir
@type t() :: %Md.Parser.Error{
  __exception__: term(),
  bag: map(),
  continuation: binary(),
  hint: String.t() | nil,
  message: String.t(),
  mode: [Md.Listener.parse_mode()],
  parser: module(),
  path: [Md.Listener.trace()]
}
```

Everything captured at the point the parser got stuck

# `build`

```elixir
@spec build(term(), Md.Parser.State.t(), module()) :: t()
```

Builds the exception without raising it. Exposed for testing.

# `raise!`

```elixir
@spec raise!(binary(), Md.Parser.State.t(), module()) :: no_return()
```

Reports the failure and raises `Md.Parser.Error`.

Called by the generated catch-all `do_parse/2` clause; not part of the
public API.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
