Phoenix框架调试时出现Endpoint.path/1未定义错误求助
调试Phoenix视图时出现“Endpoint.path/1 is undefined”错误解决方法
问题现象
手动调用Phoenix.View.render_to_string/3渲染登录页面模板时触发错误,具体报错如下:
iex(22)> Phoenix.View.render_to_string(PenWeb.LoginView, "show.html", message: "Hello from IEx!") ** (UndefinedFunctionError) function Endpoint.path/1 is undefined (module Endpoint is not available) Endpoint.path("/login") lib/pen_web/templates/login/show.html.heex:2: anonymous fn/2 in PenWeb.LoginView."show.html"/1 (phoenix_live_view 0.17.11) lib/phoenix_live_view/engine.ex:124: Phoenix.HTML.Safe.Phoenix.LiveView.Rendered.to_iodata/1 (phoenix_view 1.1.2) lib/phoenix/view.ex:482: Phoenix.View.render_to_string/3
相关代码片段
登录模板(show.html.heex)
<h2>Log in</h2> <%= form_tag(Routes.login_path(Endpoint, :create)) do %> <div class="form-group"> <label for="username">Username or Email</label> <input id="username" type="text" class="form-control" name="username"> </div> <div class="form-group"> <label for="password">Password</label> <!--span style="float: right;"><a href="<%= Routes.password_reset_path(Endpoint, :show) %>">Forgot your password?</a></span--> <input id="password" type="password" class="form-control" name="password"> </div> <!--input type="hidden" name="return" value="<%= @return %>"--> <button type="submit" class="btn btn-primary">Log in</button> <br><br> <% end %>
LoginView定义(login_view.ex)
defmodule PenWeb.LoginView do use PenWeb, :view end
项目路由列表
macbook:pen yuchen$ mix phx.routes page_path GET / PenWeb.PageController :index login_path GET /login PenWeb.LoginController :show login_path POST /login PenWeb.LoginController :create login_path POST /logout PenWeb.LoginController :delete live_dashboard_path GET /dashboard Phoenix.LiveDashboard.PageLive :home live_dashboard_path GET /dashboard/:page Phoenix.LiveDashboard.PageLive :page live_dashboard_path GET /dashboard/:node/:page Phoenix.LiveDashboard.PageLive :page * /dev/mailbox Plug.Swoosh.MailboxPreview []
PenWeb的view宏定义
def view do quote do use Phoenix.View, root: "lib/pen_web/templates", namespace: PenWeb # Import convenience functions from controllers import Phoenix.Controller, only: [get_flash: 1, get_flash: 2, view_module: 1, view_template: 1] # Include shared imports and aliases for views unquote(view_helpers()) end end
view_helpers辅助函数
defp view_helpers do quote do # Use all HTML functionality (forms, tags, etc) use Phoenix.HTML # Import LiveView and .heex helpers (live_render, live_patch, <.form>, etc) import Phoenix.LiveView.Helpers # Import basic rendering functionality (render, render_layout, etc) import Phoenix.View import PenWeb.ErrorHelpers import PenWeb.Gettext alias PenWeb.Router.Helpers, as: Routes end end
问题原因
模板中调用Routes.login_path(Endpoint, :create)时,直接使用了Endpoint模块名,但当前视图模块并未导入或别名项目的PenWeb.Endpoint,导致渲染时无法找到该模块,进而触发UndefinedFunctionError。
解决方法
方法一:全局添加Endpoint别名(推荐)
修改view_helpers函数,新增PenWeb.Endpoint的别名,这样所有视图都能直接使用Endpoint:
defp view_helpers do quote do # 原有代码保持不变 alias PenWeb.Router.Helpers, as: Routes alias PenWeb.Endpoint # 新增这一行 end end
方法二:模板中使用完整模块名
直接在模板里替换Endpoint为PenWeb.Endpoint:
<%= form_tag(Routes.login_path(PenWeb.Endpoint, :create)) do %>
方法三:临时在IEx中传入Endpoint变量
如果只是临时调试,可在调用render_to_string时手动传入Endpoint变量:
Phoenix.View.render_to_string(PenWeb.LoginView, "show.html", message: "Hello from IEx!", Endpoint: PenWeb.Endpoint)
内容的提问来源于stack exchange,提问作者Chen Yu
相关产品推荐
相关产品推荐

