Hello there,
The only way I found to provide a verified route as options to a plug is the following syntax:
plug AppWeb.Plugs.ManageBackPath, default_path_fn: &AppWeb.RoomController.room_path/0
def room_path, do: ~p"/rooms"
I tried an anonymous function
plug AppWeb.Plugs.ManageBackPath, default_path_fn: fn -> ~p"/rooms" end
I get
== Compilation error in file lib/app_web/controllers/room/room_controller.ex ==
** (ArgumentError) cannot escape #Function<0.100776851/1 in :elixir_compiler_203.__MODULE__/1>. The supported values are: lists, tuples, maps, atoms, numbers, bitstrings, PIDs and remote functions in the format &Mod.fun/arity
And of course
plug AppWeb.Plugs.ManageBackPath, default_path_fn: ~p"/rooms"
Gives
== Compilation error in file lib/app_web/controllers/room/room_controller.ex ==
** (RuntimeError) Phoenix.VerifiedRoutes can only be used inside functions, please move your usage of ~p to functions
Having to define a full function for each param seems to be the only accepted syntax, but having a public function in my controller looks wrong too.
It’s probably possible to hide that in a macro… but not convinced this is the best path to take.
1 Like
One other option is to use a plain route option and in your plug’s init/1
use route_info/4
to validate. Just raise on :error
and it will produce a compile-time error.
1 Like
Won’t that produce a runtime only error though?
It could work for our use case however, a runtime error at the plug level means we’d catch it pretty early if we were to change the route.
def init(default_path: default_path) do
case Phoenix.Router.route_info(AppWeb.Router, "GET", default_path, nil) do
:error -> raise ArgumentError, "Invalid default_path: #{default_path}"
_ -> default_path
end
end
that’s what I got
Try compiling with prod
Mix environment. It should raise the error.
1 Like
Wow! I wasn’t aware of this at all
Can you point me to some documentation? I’m trying right now with :test
env because I’d want it to fail the CI before the prod build too.
EDIT: doesn’t say anyhting in test, i’ll see if we can / want to change that.
EDIT2: yep, we got that in config_test.exs
, i’m going to bench
# Initialize plugs at runtime for faster test compilation
config :phoenix, :plug_init_mode, :runtime
EDIT3: 1mn30 to 1mn45, not worth the loss, it’s goind to fail anway on relase. Thanks a lot!
1 Like
Plugs init/1 callback is executed at compile time by default, which can be changed by configuring plugs :init_mode
to :runtime
. The latter is set by phoenix for :dev
to keep compile times quicker.
2 Likes