Why :erlang.convert_time_unit throws :badarg?


#1

I am writing a library for job processing (https://github.com/mspanc/jumbo)

I have found out that :erlang.convert_time_unit(1236133, :native, :millisecond) can throw :badarg but only on some platforms. This code works perfecly on my laptop (mac os x, elixir 1.3.4 installed via brew) but fails on dokku-based, ubuntu-based docker .

Any clue, why?

Seems that on Erlang 19 it works fine, has something significant changed from 18?

2017-01-11T12:50:28.078994834Z app[web.1]: ** (ArgumentError) argument error
2017-01-11T12:50:28.079061075Z app[web.1]:     :erlang.convert_time_unit(1236133, :native, :millisecond)
2017-01-11T12:50:28.079078719Z app[web.1]:     (jumbo) lib/jumbo/queue.ex:365: anonymous fn/5 in Jumbo.Queue.do_enqueue_job/5
2017-01-11T12:50:28.079128689Z app[web.1]:     (elixir) lib/task/supervised.ex:94: Task.Supervised.do_apply/2
2017-01-11T12:50:28.079147632Z app[web.1]:     (elixir) lib/task/supervised.ex:45: Task.Supervised.reply/5
2017-01-11T12:50:28.079198182Z app[web.1]:     (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
2017-01-11T12:50:28.079217862Z app[web.1]: Function: #Function<0.118922442/0 in Jumbo.Queue.do_enqueue_job/5>

#2

Hmm unsure, it works here on Windows as well. So Let’s take a look at the source:

So, it looks like its first chance to return a bad argument error is at:

Thus that can only happen if a non-int64 was passed in, and your number is static and smaller, so it should be fine.

And, hmm, I’m not seeing any other badarg calls anywhere else down in to its callstack…

That makes me wonder, is Erlang a 32-bit or 64-bit on your laptop? Is Erlang a 32-bit or 64-bit on your dokku-thing?


#3

I have managed to reproduce it on my local box. I use just ubuntu 16.04 64-bit, erlang is in version 18.3-dfsg-1ubuntu3. Seems that no call to this function works properly.

I even tried in plain erl shell to see whether it is not an elixir issue:

5> erlang:convert_time_unit(1, second, native).      
** exception error: bad argument
     in function  erlang:convert_time_unit/3
        called as erlang:convert_time_unit(1,second,native)

It seems to work with erlang 19 but it introduces some issues with SSL so I do not want to migrate.


#4

I have made a bug report upstream: https://bugs.erlang.org/browse/ERL-339