IEX error shell process exited with reason: :shell_funs_only

Background

I have a module that I am copy/pasting into an IEx session connected to an app. However I can’t run it because I get the following error:

** (EXIT from #PID<0.15040.0>) shell process exited with reason: :shell_funs_only

Code

Here is the code:

defmodule ReconTracer do
  use GenServer

  defmodule State do
    defstruct max_calls: 1, modules: [], index: 0
  end

  @spec start_link(non_neg_integer) :: :ignore | {:error, any} | {:ok, pid}
  def start_link(max_calls), do:
    GenServer.start_link(__MODULE__, max_calls, name: __MODULE__)

  @spec set_max_calls(non_neg_integer) :: {:ok, integer}
  def set_max_calls(new_val), do:
    GenServer.call(__MODULE__, {:set_max_calls, new_val})

  @spec next :: {:ok, {module, :handle_info, :_}, integer}
  def next, do: GenServer.call(__MODULE__, :next)

  @spec jump_at(non_neg_integer) :: {:ok, {module, :handle_info, :_}, integer}
  def jump_at(new_index), do: GenServer.call(__MODULE__, {:jump_at, new_index})

  @impl GenServer
  def init(max_calls) do
    mods =
      :code.all_loaded()
      |> Stream.map(fn({module, _path}) -> module end)
      |> Enum.map(&{&1, :_, fn(args) ->
        case false do
          true  -> :ok
          false -> :nok
        end
      end})

    state = %State{max_calls: max_calls, modules: mods}
    watch_perp(state)

    {:ok, state}
  end

  @impl GenServer
  def handle_call(:next, _from, state) do

    new_index = state.index + 1
    if new_index >= length(state.modules) do
      {:reply, {:ok, :end, state.index}, state}
    else
      new_state = %State{state | index: new_index}
      perp = watch_perp(new_state)
      {:reply, {:ok, perp, new_state.index}, new_state}
    end
  end

  @impl GenServer
  def handle_call({:set_max_calls, new_val}, _from, state) do
    new_state = %State{state | max_calls: new_val}
    {:reply, {:ok, new_val}, new_state}
  end

  @impl GenServer
  def handle_call({:jump_at, new_index}, _from, state) do
    new_state = %State{state | index: new_index}
    perp = watch_perp(new_state)
    {:reply, {:ok, perp, new_state.index}, new_state}
  end

  defp watch_perp(state) do
    perp = Enum.at(state.modules, state.index)
    :recon_trace.calls(perp, state.max_calls)
    perp
  end

end

Question

The error occurs when I run ReconTracer.start_link(100).

  1. What does the error mean?
  2. How can I fix my code so it runs on IEx?

I found out this is happening because the function I am passing to recon_trace is not compatible with match specifications.

If fix that, the GenServer code works.

1 Like