esl / erlang_ale

Erlang Actor Library for Embedded -- An embedded framework from Erlang Solutions
Apache License 2.0
207 stars 65 forks source link

Error handling #33

Open G3UKB opened 6 years ago

G3UKB commented 6 years ago

This is probably me not understanding erlang error handling. This snippet tries to open a non-existent device but it still gets {ok, Pid} plus an error message. The write then fails with an exception. The docs say error returns are (error, reason} which I don't understand. Why are they both atoms? The question is how to correctly catch errors.

`-module(e). -export([f/0]).

f() -> case i2c:start_link("i2c-3", 16#40) of {ok, D} -> io:format("OK~n"), case i2c:write(D, <<16#00, 16#00>>) of ok -> ok; {error, Reason1} -> io:format("Reason1: ~w~n", [Reason1]) end; {error, Reason} -> io:format("Reason: ~w~n", [Reason]) end.`

51> e:f(). OK erlang-ale: open /dev/i2c-3: No such file or directory ** exception exit: {timeout,{gen_server,call,[<0.396.0>,{write,<<0,0>>}]}} in function gen_server:call/2 (gen_server.erl, line 206) in call from e:f/0 (e.erl, line 7) 52>

altishchenko commented 6 years ago

@G3UKB Bob,

  1. You are getting 'timeout' from i2c:write/2.
  2. It comes as an exception from 'gen_server:call' - no process listening on that port.

That means that some errors (obvious) are processed and returned by i2c:write, but some problematic situations do call for exceptions. You may use 'catch' or 'try/catch' to handle that, but remember - in Erlang there is a paradigm - 'Let it fail!' and 'Make as many processes as may be restarted'. Drop me a note if you want more inside details.

G3UKB commented 6 years ago

Thanks Alexander, My providers SMTP server seems to be down so can't send emails at the moment.

I think that does answer the question. At the moment I am letting the process fail by simply only handling the necessary good cases. As that process runs on the Pi I'm sure I can arrange for it to be restarted if that is the right thing to do. However, if say the hardware isn't connected/responding how would I get the correct error information back to the client. At the moment i2c:start_link does not return an error but rather prints it to the console and returns an ok. The following timeout exception on the write could be deduced to be because the device was not opened but its not obvious.