# `Linx.NFT.ParseError`
[🔗](https://github.com/oshlabs/linx/blob/v0.2.0/lib/linx/nft/parse_error.ex#L1)

Syntax error raised by the `~NFT` sigil, by `Linx.NFT.parse/1` /
`parse_file/1`, and by the AST-walker compiler.

Carries the source location (`{file, line, column}`) plus the
offending source line for caret rendering — modelled on the
Elixir compiler's own error output and on
`Phoenix.LiveView.TagEngine.Tokenizer.ParseError`.

## Fields

  * `:file` — source file name (or `"nofile"` for sigils without
    explicit location).
  * `:line` — 1-based line number of the offending token.
  * `:column` — 1-based column.
  * `:snippet` — the source line as it appears (no trailing
    newline), shown above the caret. May be `nil` when the
    tokenizer wasn't carrying source context.
  * `:message` — short, human-readable description.

## Rendering

`Exception.message/1` produces a multi-line message of the form:

    myapp.nft:42:5: unexpected character '?'
    |
    | tcp dport ? accept
    |           ^

matching the look of compiler diagnostics elsewhere in the
Elixir ecosystem.

# `t`

```elixir
@type t() :: %Linx.NFT.ParseError{
  __exception__: true,
  column: pos_integer(),
  file: String.t(),
  line: pos_integer(),
  message: String.t(),
  snippet: String.t() | nil
}
```

# `code_snippet`

```elixir
@spec code_snippet(String.t() | nil, pos_integer()) :: String.t()
```

Renders the offending source line plus a caret pointing at the
given (1-based) `column`, in the same format the Elixir compiler
uses for syntax errors:

    |
    | tcp dport 22
    |     ^

Returns the empty string when `line` is `nil` (no source context
was captured).

# `raise_syntax_error!`

```elixir
@spec raise_syntax_error!(map(), String.t()) :: no_return()
```

Convenience constructor used by the tokenizer / parser / compiler.

`ctx` is any map carrying `:file`, `:line`, `:column`, and
optionally `:snippet`. Always raises — never returns.

---

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