Skip to content

Improve error message for Ecto.Enum in queries #4672

@wojtekmach

Description

@wojtekmach

Elixir version

1.19.0

Database and Version

Postgres

Ecto Versions

main

Database Adapter and Versions (postgrex, myxql, etc)

main

Current behavior

Say I have this field:

field(:category, Ecto.Enum, values: ~w[news sports]a)

and this query:

categories = ["news", "news2"]
Repo.all(from(p in Post, where: p.category in ^categories))

Currently, I get this error:

** (Ecto.Query.CastError) ecto_sql.exs:55: value `["news", "news2"]` in `where` cannot be
 cast to type {:in, {:parameterized, {Ecto.Enum, %{on_load: %{"news" => :news, "sports" =
> :sports}, type: :string, embed_as: :self, on_dump: %{news: "news", sports: "sports"}, o
n_cast: %{"news" => :news, "sports" => :sports}, mappings: [news: "news", sports: "sports
"]}}}} in query:

from p0 in Post,
  where: p0.category in ^["news", "news2"],
  select: p0

    (elixir 1.20.0-dev) lib/enum.ex:2595: Enum."-reduce/3-lists^foldl/2-0-"/3
    (elixir 1.20.0-dev) lib/enum.ex:1829: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3

I think it would be nice to get a more direct error message.

Full snippet below:

Mix.install([
  {:ecto, github: "elixir-ecto/ecto", override: true},
  {:ecto_sql, github: "elixir-ecto/ecto_sql", override: true},
  {:postgrex, ">= 0.0.0"}
  # {:myxql, ">= 0.0.0"}
  # {:ecto_sqlite3, "~> 0.17"}
])

Application.put_env(:myapp, Repo, database: "mix_install_examples")

defmodule Repo do
  use Ecto.Repo, adapter: Ecto.Adapters.Postgres, otp_app: :myapp
  # use Ecto.Repo, adapter: Ecto.Adapters.MyXQL, otp_app: :myapp
  # use Ecto.Repo, adapter: Ecto.Adapters.SQLite3, otp_app: :myapp
end

defmodule Migration do
  use Ecto.Migration

  def change do
    create table("posts") do
      add(:title, :string)
      add(:category, :string)
      timestamps(type: :utc_datetime_usec)
    end
  end
end

defmodule Post do
  use Ecto.Schema

  schema "posts" do
    field(:title, :string)
    field(:category, Ecto.Enum, values: ~w[news sports]a)
    timestamps(type: :utc_datetime_usec)
  end
end

defmodule Main do
  import Ecto.Query, warn: false

  def main do
    Repo.__adapter__().storage_down(Repo.config())
    :ok = Repo.__adapter__().storage_up(Repo.config())
    {:ok, _} = Repo.start_link([])
    Ecto.Migrator.run(Repo, [{0, Migration}], :up, all: true, log_migrations_sql: :info)

    Repo.insert!(%Post{
      title: "Post 1",
      category: :news
    })

    categories = ["news", "news2"]

    Repo.all(from(p in Post, where: p.category in ^categories))
    |> dbg()
  end
end

Main.main()

Expected behavior

Improved error message.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions