Erlang Examples: GUIs and Error Handling

July 31, 2008 - 3 minute read -
erlang exercises

This is part of a series on the Erlang Exercises which is a great set of programming problems that challenge you to implement solutions to some common Erlang problems. I'm going to share some of my solutions to these problems.

Robustness in Erlang, and use of a graphics package

Excercise: Create a window containing three buttons: Quit , Spawn , Error. The Spawn button shall create a child process which displays an identical window. The Quit button should kill the window and its child windows. The Error button should cause a runtime error that kills the window (and its children), this window shall then be restarted by its parent.

-module(gui).
-export([init/0]).</p>
<p>init() ->
    S = gs:start(),
    Win = gs:create(window, S, [{width, 350}, {height, 100}]),
    gs:create(button, quit, Win, [{label, {text, "Quit"}}, {x, 0}]),
    gs:create(button, spawn, Win, [{label, {text, "Spawn"}}, {x, 100}]),
    gs:create(button, error, Win, [{label, {text, "Error"}}, {x, 200}]),
    gs:config(Win, {map, true}),
    loop().</p>
<p>loop() ->
    receive
        {gs, spawn, click, _, _} ->
            Pid = spawn(?MODULE, init, []),
            handle_error(self(), Pid),
            io:format("got here~n",[]),
            loop();
        {gs, quit, click, _, _} ->
            io:format("quitting~n",[]),
            gs:stop();
        {gs, error, click, _, _} ->
            erlang:error(errorclick);
        exit ->
            bye
    end.</p>
<p>handle_error(MasterPid, Pid) ->
    spawn(fun() ->
                  process_flag(trap_exit, true),
                  link(Pid),
                  receive
                      {'EXIT', Pid, {errorclick, _}} ->
                          io:format(" ~p died :~n",[Pid]),
                          MasterPid ! {gs, spawn, click, a, b};
                      _ ->
                          io:format(" really quitting :~n", []),
                          MasterPid ! exit
                  end
          end).

gs

The gs code is all GUI code. It just goes to show that you can use FP to create GUIs even if it's not quite as intuitive as it might be in an OO language. It creates a windows with a series of buttons on it.

handle_error

This handle_error code shows linking a Process to another error handler process. That spawns a process whose sole purpose is to listen for errors from the main process. If an {'EXIT', Pid, {errorclick, _}} error is received the error handler sends a message back asking the MasterPid to spawn a new window.