Runtime checks are not executed in development
darioghilardi opened this issue · comments
Environment
- Elixir version: 1.13.4
- Domo version: 1.5.3
- TypedStruct version: 0.3.0
Actual behavior
First of all: thanks a lot for this great library.
Here is the issue: I defined a module like this:
defmodule DomoTest.Schema do
use Domo
use TypedStruct
typedstruct enforce: true do
field(:one, String.t())
field(:two, boolean())
field(:three, integer())
end
end
When running iex -S mix
the library works as expected:
iex> DomoTest.Schema.new(%{one: "aaa", two: 23, three: false})
{:error,
[
two: "Invalid value 23 for field :two of %DomoTest.Schema{}. Expected the value matching the false | true type.",
three: "Invalid value false for field :three of %DomoTest.Schema{}. Expected the value matching the integer() type."
]}
But when running the phoenix server in development mode the library doesn't work as expected:
DomoTest.Schema.new(%{one: "aaa", two: 23, three: false})
{:ok, %DomoTest.Schema{one: "aaa", three: false, two: 23}}
I created a minimal repository to replicate the issue. The creation of the struct happens in page_controller.ex
.
Note however that if I start the phoenix app with MIX_ENV=prod
domo starts to do its job and for the exact same code returns:
{:error,
[
two: "Invalid value 23 for field :two of %DomoTest.Schema{}. Expected the value matching the false | true type.",
three: "Invalid value false for field :three of %DomoTest.Schema{}. Expected the value matching the integer() type."
]}
Expected behavior
I expect a consistent behavior, with runtime checks executed in development.
Thank you.
From a quick debugging session it seems that Phoenix's CodeReloader triggers Mix.Tasks.Compile.DomoCompiler.run
every time, but the code paths never end up calling Mix.Tasks.Compile.DomoCompiler.stop_plan_collection
, thus causing the generated .new
/.new!
functions to always skip validation.
Fixed by ba9e28d
Thanks!
Thank you! 👍
Hey,
@darioghilardi thanks for raising the issue, and thanks @razielgn for the diagnostics.
Yes, the stop_plan_collection
function was never called because elixirs :after_compile
hook is not executed because Phoenix runs compilers one by one with Mix.Task.run("compile.xxx")
instead of compile.all
. That's by Phoenix design.
As for the solution, you can upgrade to Domo version 1.5.4 with :domo_phoenix_hot_reload
compile task included, which you can put after :elixir
to the compilers
list in the mix.exs file and to the reloadable_compilers
list in the config file. As the following:
# in mix.exs
compilers: [:domo_compiler] ++ Mix.compilers() ++ [:domo_phoenix_hot_reload]
# in dev.exs
config :my_app, MyApp.Endpoint,
reloadable_compilers: [:phoenix, :domo_compiler] ++ Mix.compilers() ++ [:domo_phoenix_hot_reload]
This brings fast prototyping with Phoenix and Domo back on track 🤘