【问题标题】:Ecto changesets and Dialyzer errorsEcto 变更集和透析器错误
【发布时间】:2017-03-01 20:59:08
【问题描述】:

我有一个伞式应用程序。我看到了 Dialyzer 的价值,我正在尝试开始使用它。我已经走了很远,但我有一个无法解决的关于 Ecto 的问题。

这适用于处理身份验证的伞形小应用程序。我可以用最简单的例子来简化它。

使用 Elixir 1.4.2 和 Dialyxir 0.4.0。

问题中的代码

defmodule Auth.Account do
  use Ecto.Schema
  import Ecto.Changeset

  schema "auth_accounts" do
    field :email, :string
    field :password_hash, :string
    field :password, :string, virtual: true

    timestamps()
  end

  def build(params \\ %{}) do
    changeset(%__MODULE__{}, params)
  end

  def changeset(account, params \\ %{}) do
    account
    |> cast(params, ~w(email password))
  end
end

相关错误输出

lib/auth/account.ex:13: Function build/0 has no local return
lib/auth/account.ex:13: Function build/1 has no local return
lib/auth/account.ex:14: The call 'Elixir.Auth.Account':changeset(#{'__meta__':=#{'__struct__':='Elixir.Ecto.Schema.Metadata', 'context':='nil', 'source':={'nil',<<_:104>>}, 'state':='built'}, '__struct__':='Elixir.Auth.Account', 'email':='nil', 'id':='nil', 'inserted_at':='nil', 'password':='nil', 'password_hash':='nil', 'updated_at':='nil'},params@1::any()) 
  will never return since it differs in the 1st argument from the success typing arguments: ({map(),map()} | #{'__struct__':=atom(), 'action'=>'delete' | 'insert' | 'nil' | 'replace' | 'update', 'changes'=>#{atom()=>_}, 'constraints'=>[#{'constraint':=binary(), 'field':=atom(), 'match':='exact' | 'suffix', 'message':={_,_}, 'type':='unique'}], 'data'=>'nil' | #{'__struct__':=atom()}, 'empty_values'=>_, 'errors'=>[{atom(),{_,_}}], 'filters'=>#{atom()=>_}, 'params'=>'nil' | #{binary()=>_}, 'prepare'=>[fun((map()) -> map())], 'repo'=>atom(), 'required'=>[atom()], 'types'=>'nil' | #{atom()=>atom() | {'array',_} | {'embed',map()} | {'in',_} | {'map',_}}, 'valid?'=>boolean(), 'validations'=>[{atom(),_}]},'invalid' | #{'__struct__'=>none(), atom() | binary()=>_})

看来问题在于build 函数对%__MODULE__{} 的使用。请参阅此相关Stack Overflow Topic

但是,我就是想不出一个有效的替代语法。

【问题讨论】:

  • 这是否修复了警告? def build(params \\ %{}) do?
  • 很遗憾没有。我更新了上面的代码,以免混淆其他人。但我只是重新测试验证。问题依然存在。确保重建 PLT。
  • 暂缓一下,如果我将您的确切代码复制粘贴到新的混合包中,我将无法在本地重现此内容。您使用的是哪个版本的 Ecto?如果您将该模块复制到一个全新的混合包中,您是否能够重现这一点? (FWIW 我认为此错误与您链接到的其他问题无关。)
  • 纯粹为了一些可能有用的背景上下文,许多核心或常用的 Elixir 库本身并不使用(即定期运行)Dialyzer,并且有一些类型规范错误可能导致 Dialyzer对使用这些库的代码发出警告。幸运的是,这些库几乎都写得很好,因此自己很容易阅读。

标签: elixir ecto dialyzer


【解决方案1】:

Dogbert 无法重现它,促使我深入挖掘。

我在 ecto ~> 2.0. mix.lock 文件让我处于 2.0.5。在mix deps.unlock --allmix deps.clean --allmix deps.get 之后,我升级到了ecto 2.1.3。

库升级后,透析器不再抱怨这个。所以我的解决办法是升级到更新的 ecto 版本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多