emeryotopalik
Hello. I am experiencing an unexpected behavior with the way Elixir is handling a guard clause exception. Take the following:
defmodule Foo do
def eval(x, percentage) when rem(x, 100) < percentage, do: true
def eval(_, _), do: false
end
Foo.eval(nil, 20) # Sometimes this is false, sometimes it is true
I have a function very similar to the one above running in my application. Occasionally, I pass x = nil to the function. I would expect there to ALWAYS be an Arithmetic Exception stemming from calling rem(nil, 100) and thus the guard would fail and we would catch the next eval function head.
But, that is not the case. I’ve tried digging into the Elixir source code to decipher how exceptions are handled in guards, but I get a bit turned around. My best guess is that the exception is being compared in the < evaluation itself, and thus the flakiness? I truly do not know.
I do understand that the way to fix this would be to first check is_integer(x). I am merely trying to understand why the exception is being handled as I expect in the first place.
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ai
- #ecto-query
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #metaprogramming
- #hex











Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
trisolaran
I tried your code.
Foo.eval(nil, 20)always returnsfalseto me.stefanluptak
Same here:
emeryotopalik
I wonder if this is maybe only reproducible in an application. When I run this code in
iex, I agree it always returns false.dimitarvp
Maybe you’re using an older Elixir version for your app?
al2o3cr
Exceptions aren’t propagated outside the guard, they are considered “failure to match”:
(from the Erlang reference manual)
I’d guess the intent was to avoid having to spam
is_integerand similar checks.rvirding
Yes, we felt that it was better to be consistent and have all exceptions in guards just cause the guard to fail. It could otherwise sometimes be very difficult to add tests to avoid all errors in guards.
emeryotopalik
Nah, on 1.12
eksperimental
I can confirm this issue. As I have managed to reproduce it @emeryotopalik
And it sounds like a serious one. And when it fails, it fails repeatedly for a while until it may go back to normal, and then it may fail again.
I am running Arch Linux 64bits, and my
elixir --versionis:OTP 24.1.2
mix testfails big time:Now I run it with OTP 23.3.4.9 ,
mix testpass all tests,here are the commands on IEx:
…and it’s all good.
So my quick assumption is that this is due the the JIT compiler introduced in OTP24
I have created a project for things like this, where I test an Elixir project in every Elixir/OTP version combination.
and suprisingly it does not fail for OTP 24 with JIT. (it only fails with OTP 17, and it does not even compile, so that is unrelated).
https://github.com/eksperimental/debug_me/runs/4491828158?check_suite_focus=true
the source code of Elixir project can be found here:
GitHub - eksperimental/debug_me at emeryotopalik · GitHub
UPDATE 1:
And Noticed that when it fails it fails after ~600 results (or multiple of this number), after running
MIX_ENV=test mix do compile --force, testmultiple times:these 2 are from the same compilation:
then I got:
krstfk
I believe this has to do with this bug :https://github.com/erlang/otp/issues/5401 which has been fixed with https://github.com/erlang/otp/pull/5409 and was part of the erts 12.1.4 (I believe released with Erlang 24.1.5).
I could not reproducer using your repo :
emeryotopalik
Updated and it seems to be working consistently for me now! Thanks for the spot.