Correct usage of @after_verify in Phoenix app

Code.Typespec.fetch_specs(module) errors out when used inside a __after_verify__. But it works well in a LiveBook or even inn IEx session. Here is the full code. Any pointers?

defmodule Aa do
  defmacro __using__(_) do
    quote do
      @after_verify Aa
    end
  end

  def __after_verify__(module) do
    result = Code.Typespec.fetch_specs(module)
    IO.inspect(result, label: "fetch_specs result")
  end
end

defmodule TestFunc do
  use Aa
end

$ iex -S mix phx.server
Erlang/OTP 25 [erts-13.1.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Compiling 2 files (.ex)
fetch_specs result: :error
[info] Running HbotWeb.Endpoint with cowboy 2.10.0 at 127.0.0.1:4000 (http)

iex(2)> Code.Typespec.fetch_specs(TestFunc)
{:ok,
 [...]

fetch_specs is available after the module is written to disk. When the compiler is running after_verify, the module has not been written to disk yet. What you are trying to achieve is not currently possible.

2 Likes

Thanks. I am trying to build a module of functions and supply that to OpenAI function calling. Something like this:

  def __after_verify__(module) do
    specs = Code.Typespec.fetch_specs(module)
    docs = Code.fetch_docs(module)
    # process specs and docs
  end

What’s the best way to do it?

Can you build the specification at runtime instead? When you pass a module, you build the specification and you can cache it somewhere.