I am very new to Elixir
. I am facing this error:
2022-07-06 13:52:53.022 [info] pid=<0.31.0> Application mt_consumer exited: MTConsumer.Application.start(:normal, []) returned an error: shutdown: failed to start child: MTConsumer
** (EXIT) an exception was raised:
** (ArgumentError) comparison with nil is forbidden as it is unsafe. If you want to check if a value is nil, use is_nil/1 instead
(ecto) lib/ecto/query/builder.ex:551: Ecto.Query.Builder.not_nil!/1
(mt_model) lib/mt_model/location.ex:36: MTModel.Location.raw_id_by_name_tenant/2
(mt_consumer) lib/mt_consumer.ex:66: MTConsumer.handle_job/1
(mt_consumer) lib/mt_consumer.ex:38: MTConsumer.loop/1
(stdlib) supervisor.erl:365: :supervisor.do_start_child/2
(stdlib) supervisor.erl:348: :supervisor.start_children/3
(stdlib) supervisor.erl:314: :supervisor.init_children/2
(stdlib) gen_server.erl:328: :gen_server.init_it/6
Now here is my code:
def id_by_name_tenant(name, tenant_id) do
id = raw_id_by_name_tenant(name, tenant_id)
case id do
nil -> raw_id_by_name_tenant(@default_name, nil)
_ -> id
end
end
defp raw_id_by_name_tenant(name, tenant_id) do
from(
l in MTModel.Location,
where: l.name == ^name and l.tenant_id == ^tenant_id,
limit: 1,
select: l.id
) |> MTModel.Repo.one([])
end
defp raw_id_by_name_tenant(name, _) do
from(
l in MTModel.Location,
where: l.name == ^name,
limit: 1,
select: l.id
) |> MTModel.Repo.one()
end
what am I doing wrong here? The code worked fine earlier but upon re deploying it started creating problems.
The second clause of raw_id_by_name_tenant/2
will never match, since the first one will always do. You probably forgot to guard against nil
in the first clause, for example
defp raw_id_by_name_tenant(name, tenant_id) when tenant_id != nil do
or move the second clause up and replace it with
defp raw_id_by_name_tenant(name, nil) do
But I think you might be able to simplify this code by using Repo.get_by/2
, removing the need for a private function and making the intent clearer (if your name/tenant_id pairs are unique):
def id_by_name_tenant(name, tenant_id) do
query = select(MTModel.Location, [l], l.id)
case Repo.get_by(query, name: name, tenant_id: tenant_id) do
nil -> Repo.get_by(query, name: @default_name)
id -> id
end
end