Md.Parser.Error exception (md v0.15.1)

Copy Markdown View Source

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.

Summary

Types

t()

Everything captured at the point the parser got stuck

Functions

Builds the exception without raising it. Exposed for testing.

Reports the failure and raises Md.Parser.Error.

Types

t()

@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

Functions

build(continuation, state, parser)

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

Builds the exception without raising it. Exposed for testing.

raise!(continuation, state, parser)

@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.