When would `send` raise an error ?

In Erlang doc here, it only indicates that send function would raise error if destination is unregistered name.

But in Elixir GenServer.reply code at here, it explicitly try catch any error like following:

def reply({to, tag}, reply) when is_pid(to) do
  try do
    send(to, {tag, reply})
    :ok
  catch
    _, _ -> :ok
  end
end

Since it has is_pid(to) guard, it should not have unregistered name error anymore.

I am curious if there is any other error could be raised by send function ?

1 Like

As you can see, there is no way to call GenServer.reply with a non-pid.

However, this is possible when calling send directly. This is for instance used when working with named processes. And in those cases, if the process that the name used to refer to is no longer around (or did not start up yet), that is when send will encounter the mentioned error.

Thanks for your reply.

I got that send would raise error when it has unregistered name error, e.g. send(:no_exist, nil).

I did a bit search on git and found that is_pid guard is added at later time here. I guess try block is necessary before is_pid guard but it’s not necessary after is_pid guard added.

But if we know that pid is a pid type (with guard), would send(pid, anything) ever raise an error in other corner case?

Doesn’t sound like it, you could submit a PR :slight_smile:

http://erlang.org/doc/reference_manual/expressions.html#send

  • If Expr1 evaluates to a name, but this name is not registered, a badarg run-time error occurs.
  • Sending a message to a pid never fails, even if the pid identifies a non-existing process.
  • Distributed message sending, that is, if Expr1 evaluates to a tuple {Name,Node} (or a pid located at another node), also never fails.

Good idea !

Here we go: https://github.com/elixir-lang/elixir/pull/8420

2 Likes

And it’s merged! :confetti_ball::tada: