View Source Babel.Trace (Babel v1.2.0)

Represents the evaluation of a Babel.Applicable. Contains the evaluated applicable, the input data, the output result, and any traces of nested Babel.Applicables.

Implements Inspect to render a human-readable version of the information.

To analyze a Babel.Trace - especially one with nested traces - find/2 will be your friend.

Inspect Options

Babel.Trace's implementation of Inspect allows you to pass two custom options:

  • depth controls how many levels of nested traces should be rendered (default 0).
    • non_neg_integer: Render nested traces until the given depth.
    • :error: Omit all non-error nested traces but render erroring traces.
    • :infinity: Render all nested traces.
  • indent controls the number of leading spaces (default 0).

You can either pass these by doing inspect(trace, custom_options: [...]) or alternatively you can use the Babel.Trace.inspect/2 function which acts as a shortcut.

Summary

Functions

Recursively checks all nested traces (and this one) against a given spec (or function).

Shortcut to inspect(trace, custom_options: opts). ## Options -depthcontrols how many levels of nested traces should be rendered (default0). *non_neg_integer: Render nested traces until the given depth. *:error: Omit all non-error nested traces but render erroring traces. *:infinity: Render all nested traces. -indentcontrols the number of leading spaces (default0`).

Reduces over the current trace and all its nested traces.

Returns the nested traces which caused the given trace to fail.

Types

@type inspect_opts() :: [
  depth: :error | :infinity | non_neg_integer(),
  indent: non_neg_integer()
]
@type t() :: t(any(), any())
@type t(output) :: t(any(), output)
@type t(input, output) :: %Babel.Trace{
  babel: Babel.t(input, output),
  input: Babel.data(),
  nested: [t()],
  output: Babel.Step.result(output)
}

Functions

@spec error?(t()) :: boolean()
@spec find(t(), function :: (t() -> boolean())) :: [t()]
@spec find(t(), spec_or_path :: spec | [spec, ...]) :: [t()]
when spec: Babel.t() | Babel.name() | (builtin_name :: atom())

Recursively checks all nested traces (and this one) against a given spec (or function).

Useful for debugging purposes.

Specs

In addition to being able to pass a function find/2 supports some convenient shortcuts:

  • name of a builtin step (e.g. :fetch or :map, see below for a full list)
  • the actual step (e.g. Babel.fetch(["fetched", "path"]))
  • a list of all of the above (incl. functions) to recursively find matching traces (e.g. [:map, :into, :fetch] to find all fetch traces inside of Babel.map(Babel.into(...)))

All builtin step names:

  • :call
  • :cast
  • :const
  • :fail
  • :fetch
  • :flat_map
  • :get
  • :identity
  • :into
  • :map
  • :match
  • :root
  • :then
  • :try

Examples

iex> pipeline = Babel.fetch("list") |> Babel.map(Babel.into(%{some_key: Babel.fetch("some key")}))
iex> data = %{"list" => [%{"some key" => "value1"}, %{"some key" => "value2"}]}
iex> trace = Babel.trace(pipeline, data)
iex> Babel.Trace.find(trace, &Babel.Trace.error?/1)
[]
iex> Babel.Trace.find(trace, :fetch)
[
  Babel.trace(Babel.fetch("list"), data),
  Babel.trace(Babel.fetch("some key"), %{"some key" => "value1"}),
  Babel.trace(Babel.fetch("some key"), %{"some key" => "value2"}),
]
iex> Babel.Trace.find(trace, Babel.fetch("list"))
[
  Babel.trace(Babel.fetch("list"), data)
]
iex> Babel.Trace.find(trace, [:into, :fetch])
[
  Babel.trace(Babel.fetch("some key"), %{"some key" => "value1"}),
  Babel.trace(Babel.fetch("some key"), %{"some key" => "value2"}),
]
Link to this function

inspect(trace, opts \\ [])

View Source
@spec inspect(t(), inspect_opts()) :: String.t()

Shortcut to inspect(trace, custom_options: opts). ## Options -depthcontrols how many levels of nested traces should be rendered (default0). *non_neg_integer: Render nested traces until the given depth. *:error: Omit all non-error nested traces but render erroring traces. *:infinity: Render all nested traces. -indentcontrols the number of leading spaces (default0`).

Link to this function

matches_spec?(babel, spec)

View Source
Link to this function

new(babel, input, output, nested \\ [])

View Source
@spec new(
  babel :: Babel.t(input, output),
  input :: input | Babel.Context.t(input),
  output :: Babel.Step.result(output),
  nested :: [t()]
) :: t(input, output)
when input: any(), output: any()
@spec ok?(t()) :: boolean()
@spec reduce(t(), accumulator, reducer) :: accumulator
when accumulator: any(), reducer: (t(), accumulator -> accumulator)

Reduces over the current trace and all its nested traces.

Examples

iex> pipeline = Babel.fetch("list") |> Babel.map(Babel.into(%{some_key: Babel.fetch("some key")}))
iex> data = %{"list" => [%{"some key" => "value1"}, %{"some key" => "value2"}]}
iex> trace = Babel.trace(pipeline, data)
iex> Babel.Trace.reduce(trace, 0, fn _trace, count -> count + 1 end)
7
@spec result(t()) :: {:ok, value :: any()} | {:error, reason :: any()}
@spec root_causes(t()) :: [t()]

Returns the nested traces which caused the given trace to fail.

To be specific it recursively checks all nested traces and collects all error traces which have no nested traces themselves, assuming that this implies that they were the root cause of the failure.