Skip to content

Inconsistent error message in ArgumentError exception #11416

@eksperimental

Description

@eksperimental

Environment

  • Elixir & Erlang/OTP versions (elixir --version): OTP 24, Affects Elixir versions v1.12, v1.13 and main.
  • Operating system: Linux

Current behavior

I started to notice that in some situation the same code would raise with different errors message.
I isolated the case to this:

defmodule DebugTest do
  use ExUnit.Case

  test "debug" do
    fun1 = fn(string) ->
      try do
        Atom.to_string(string)
      rescue
        exception -> {exception, __STACKTRACE__}
      end
    end

    fun2 = fn() ->
      try do
        Atom.to_string("Foo")
      rescue
        exception -> {exception, __STACKTRACE__}
      end
    end

    {exception1, stacktrace1} = fun1.("Foo")
    {exception2, stacktrace2} = fun2.()

    IO.inspect {:stacktrace1, stacktrace1}
    IO.inspect {:stacktrace2, stacktrace2}

    assert exception1 == exception2
  end
end
  1) test debug (DebugTest)
     test/elixir/debug2_test.exs:4
     Assertion with == failed
     code:  assert exception1 == exception2
     left:  %ArgumentError{__exception__: true, message: "errors were found at the given arguments:\n\n  * 1st argument: not an atom\n"}
     right: %ArgumentError{__exception__: true, message: "argument error"}
     stacktrace:
       test/elixir/debug2_test.exs:27: (test)

After searching for the this bug, with a git bisect running a TEST_FILES=debug2_test.exs make test_stdlib command, told me that it was 251413a (Adopt EEP 54) that introduced it.

fun1 in the test above, works as expected, but fun2 is missing the first entry in the stacktrace which holds the extra information,
in this example. {:erlang, :atom_to_binary, ["Foo", :utf8], [error_info: %{module: :erl_erts_errors}], making Exception.normalize/2 to give different messages.
I ported the two anonymous functions to Erlang, and checked the stacktraces are is identical, so we may probably rule out that this is happening on the Elixir side.

Eshell V12.1.2  (abort with ^G)
1>    Fn1 = fun() -> 
1>       try
1>          atom_to_binary(11111)
1>       catch
1>          error:Error:Stacktrace ->
1>             erlang:display({Error, Stacktrace})
1>       end
1>    end.
#Fun<erl_eval.45.65746770>
2>    Fn1().
{badarg,[{erlang,atom_to_binary,[11111],[{error_info,#{module=>erl_erts_errors}}]},{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,689}]},{erl_eval,try_clauses,8,[{file,"erl_eval.erl"},{line,919}]},{shell,exprs,7,[{file,"shell.erl"},{line,686}]},{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}
true
3> 
3>    Fn2 = fun(Binary) -> 
3>       try
3>          atom_to_binary(Binary)
3>       catch
3>          error:Error:Stacktrace ->
3>             erlang:display({Error, Stacktrace})
3>       end
3>     end.
#Fun<erl_eval.44.65746770>
4>    Fn2(22222).
{badarg,[{erlang,atom_to_binary,[22222],[{error_info,#{module=>erl_erts_errors}}]},{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,689}]},{erl_eval,try_clauses,8,[{file,"erl_eval.erl"},{line,919}]},{shell,exprs,7,[{file,"shell.erl"},{line,686}]},{shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},{shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}
true

Expected behavior

It should be consistent

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions