ExOutlines.Diagnostics (ExOutlines v0.1.0)

Copy Markdown View Source

Structured error representation with repair instructions.

Used to communicate validation failures and guide LLM correction.

Error Structure

Each error contains:

  • field - The field path (e.g., "user.email" or nil for top-level)
  • expected - Description of expected format/type
  • got - The actual value received
  • message - Human-readable error message

Repair Instructions

Repair instructions are generated from errors to guide LLM correction. They provide actionable steps to fix validation failures.

Summary

Functions

Add an error to existing diagnostics.

Get the number of errors in diagnostics.

Format diagnostics as a human-readable string.

Create diagnostics from a list of errors.

Check if diagnostics has any errors.

Merge multiple diagnostics into one.

Create a new diagnostics struct with a single error.

Types

error_detail()

@type error_detail() :: %{
  field: String.t() | nil,
  expected: String.t(),
  got: any(),
  message: String.t()
}

t()

@type t() :: %ExOutlines.Diagnostics{
  errors: [error_detail()],
  repair_instructions: String.t()
}

Functions

add_error(diagnostics, field, expected, got)

@spec add_error(t(), String.t() | nil, String.t(), any()) :: t()

Add an error to existing diagnostics.

Returns a new diagnostics struct with the additional error.

error_count(diagnostics)

@spec error_count(t()) :: non_neg_integer()

Get the number of errors in diagnostics.

Examples

iex> ExOutlines.Diagnostics.new("integer", "string", "age") |> ExOutlines.Diagnostics.error_count()
1

format(diagnostics)

@spec format(t()) :: String.t()

Format diagnostics as a human-readable string.

Examples

iex> diag = ExOutlines.Diagnostics.new("integer", "hello", "age")
iex> ExOutlines.Diagnostics.format(diag)
"Validation failed with 1 error:\n- [age] Field 'age': Expected integer but got \"hello\""

from_errors(errors)

@spec from_errors([error_detail()]) :: t()

Create diagnostics from a list of errors.

Each error should have :field, :expected, :got, and optionally :message.

has_errors?(diagnostics)

@spec has_errors?(t()) :: boolean()

Check if diagnostics has any errors.

Examples

iex> ExOutlines.Diagnostics.new("integer", "string", "age") |> ExOutlines.Diagnostics.has_errors?()
true

iex> %ExOutlines.Diagnostics{} |> ExOutlines.Diagnostics.has_errors?()
false

merge(diagnostics_list)

@spec merge([t()]) :: t()

Merge multiple diagnostics into one.

Combines all errors and regenerates repair instructions. Duplicate errors are automatically removed.

new(expected, got, field \\ nil)

@spec new(String.t(), any(), String.t() | nil) :: t()

Create a new diagnostics struct with a single error.

Examples

iex> ExOutlines.Diagnostics.new("integer", "hello", "age")
%ExOutlines.Diagnostics{
  errors: [%{
    field: "age",
    expected: "integer",
    got: "hello",
    message: "Field 'age': Expected integer but got \"hello\""
  }],
  repair_instructions: "Field 'age' must be: integer"
}