otp
otp copied to clipboard
ets:new/2 with named_table option - confusing behavour
Describe the bug
A call to create a named ets table with an existing name produces very confusing error message: argument 2: invalid options instead of providing more user-friendly and understandable message that a table with the given name already exists.
~~Moreover: it destroys already existing table and data.~~
To Reproduce
% erl
Erlang/OTP 25 [erts-13.0.4] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns] [dtrace]
Eshell V13.0.4 (abort with ^G)
1> ets:whereis(a).
undefined
2> ets:new(a, [named_table]).
a
3> ets:whereis(a).
#Ref<0.2920346062.238682117.68831>
4> ets:new(a, [named_table]).
** exception error: bad argument
in function ets:new/2
called as ets:new(a,[named_table])
*** argument 2: invalid options
5> ets:whereis(a).
undefined
Expected behavior
- Error message that the table already exists.
- ~~Not dropping the existing table.~~
Affected versions 25.0.4
@ilya-klyuchnikov I agree that the error message is cryptic, but the table doesn't get deleted. This only happens because you're doing it in the console and the process that owns the table crashes (the console).
Notice that there is no automatic garbage collection for tables. Even if there are no references to a table from any process, it is not automatically destroyed unless the owner process terminates.
From https://www.erlang.org/doc/man/ets.html
e.g.
Erlang/OTP 25 [erts-13.0] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit]
Eshell V13.0 (abort with ^G)
1> ets:whereis(a).
undefined
2> spawn(fun () -> ets:new(a, [named_table]), timer:sleep(1000000) end).
<0.87.0>
3> ets:whereis(a).
#Ref<0.939190476.2932998152.221476>
4> ets:new(a, [named_table]).
** exception error: bad argument
in function ets:new/2
called as ets:new(a,[named_table])
*** argument 2: invalid options
5> ets:whereis(a).
#Ref<0.939190476.2932998152.221476>
Hello! The error information for ets:new/2 is implemented here. PRs to improve it are very welcome!
As @lpgauth pointed out, the ets table dying when you get an exception is expected behaviour. You can turn this off using shell:catch_exception(true).
Not sure why this is still open, but the linked pull request is merged 😄