Errors and processes in erlang
Previous posts about http://learnyousomeerlang.com: Dog FSM, Cat FSM.
Chapter Errors And Processes is closer to the beginning of the book and deals with core Erlang concepts: error propagation and error trapping.
First off, here is what I wrote to better understand the section that starts with words “the results of uncaught throws, errors and exits in neighboring processes”:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(simple_exit_demo). | |
-export([simple_exit_demo/0]). | |
simple_exit_demo() -> | |
spawn(fun() -> start_processes() end). | |
start_processes() -> | |
process_flag(trap_exit, true), | |
spawn_link(fun() -> timer:sleep(1000) end), | |
spawn_link(fun() -> timer:sleep(2000), exit(exiting_for_a_reason) end), | |
spawn_link(fun() -> timer:sleep(3000), exit(normal) end), | |
spawn_link(fun() -> timer:sleep(4000), 1 / 0 end), | |
spawn_link(fun() -> timer:sleep(5000), erlang:error(raising_error) end), | |
spawn_link(fun() -> timer:sleep(6000), throw(throwing_error) end), | |
listen_to_exits(). | |
listen_to_exits() -> | |
receive | |
Message -> io:format("Caught a system message: ~p~n~n", [Message]), | |
listen_to_exits() | |
after 7000 -> | |
io:format("Show's over~n") | |
end. |
Here how the demo works:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
1> c(simple_exit_demo).
./simple_exit_demo.erl:12: Warning: this expression will fail with a 'badarith' exception
{ok,simple_exit_demo}
2> simple_exit_demo:simple_exit_demo().
<0.38.0>
Caught a system message: {'EXIT',<0.39.0>,normal}
Caught a system message: {'EXIT',<0.40.0>,exiting_for_a_reason}
Caught a system message: {'EXIT',<0.41.0>,normal}
Caught a system message: {'EXIT',<0.42.0>,
{badarith,
[{simple_exit_demo,
'-start_processes/0-fun-3-',0}]}}
3>
=ERROR REPORT==== 30-Dec-2011::22:42:58 ===
Error in process <0.42.0> with exit value: {badarith,[{simple_exit_demo,'-start_processes/0-fun-3-',0}]}
Caught a system message: {'EXIT',<0.43.0>,
{raising_error,
[{simple_exit_demo,
'-start_processes/0-fun-4-',0}]}}
3>
=ERROR REPORT==== 30-Dec-2011::22:42:59 ===
Error in process <0.43.0> with exit value: {raising_error,[{simple_exit_demo,'-start_processes/0-fun-4-',0}]}
=ERROR REPORT==== 30-Dec-2011::22:43:00 ===
Error in process <0.44.0> with exit value: {{nocatch,throwing_error},[{simple_exit_demo,'-start_processes/0-fun-5-',0}]}
Caught a system message: {'EXIT',<0.44.0>,
{{nocatch,throwing_error},
[{simple_exit_demo,'-start_processes/0-fun-5-',
0}]}}
Show's over
3>
The second chunk of code I’ve written helps understand how the kill reason is different from other kill reasons:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(kill). | |
-export([kill_demo/0]). | |
listen() -> | |
receive | |
Message -> io:format("~p has caught a system message: ~p~n~n", [self(), Message]), | |
listen() | |
after 1000 -> | |
io:format("I, ~p, live on~n", [self()]), | |
listen() | |
end. | |
kill_demo() -> | |
Pid = spawn_link(fun()-> | |
process_flag(trap_exit, true), | |
listen() | |
end), | |
% this will fail, the recipient process traps all exit signals | |
timer:sleep(3000), | |
io:format("Sending exit(Pid, please_die) ~p to ~n", [Pid]), | |
exit(Pid, please_die), | |
% "The kill reason acts as a special signal that can't be trapped." | |
% this will succeed | |
timer:sleep(4000), | |
io:format("Sending exit(Pid, kill) ~p to ~n", [Pid]), | |
exit(Pid, kill). |
The system process traps an exit and lives on, while exit(Pid, kill)
kills it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1> c(kill).
{ok,kill}
2> kill:kill_demo().
I, <0.38.0>, live on
I, <0.38.0>, live on
I, <0.38.0>, live on
Sending exit(Pid, please_die) <0.38.0> to
<0.38.0> has caught a system message: {'EXIT',<0.31.0>,please_die}
I, <0.38.0>, live on
I, <0.38.0>, live on
I, <0.38.0>, live on
Sending exit(Pid, kill) <0.38.0> to
** exception exit: killed
3>
December 30, 2011 | 0 Comments | Tagged erlang