[erlang-questions] Error handling with good looking code?

Attila Rajmund Nohl attila.r.nohl@REDACTED
Thu Nov 3 14:08:49 CET 2011


Hello!

I have this code (cut out some non-interesting pieces):

upload_trace_record_file2(Host, Usr, Pwd, RemDir, NetTraceRef) ->
    case sftp_client:open(Host, ?SFTP_PORT, Usr, Pwd) of
    	{ok, Pid} ->
....
	    case sftp_client:send(Pid, TRFile, RemTRFile) of
		ok ->
		    ok;
		{error, Reason} ->
		    {error, sftp_client:format_error(Reason)}
	    end,
	    sftp_client:close(Pid),
	    file:delete(TRFile);
	{error, Reason} ->
	    {error, sftp_client:format_error(Reason)}
    end.

update_trace_record_file(TRFile, NetTraceRef) ->
    case exml:read_file(TRFile, [{space, normalize}]) of
	{ok, ReadExml} ->
	    {traceCollecFile, Attributes, ChildList} = ReadExml,
...
	    file:write_file(TmpTRFile, TraceText),
	    TmpTRFile;
	_ ->
	    throw({error, bad_xml_file})
    end.

There are at least two obvious bugs in the error handling (the error
from sftp_client:send is not used; the update_trace_record_file throws
an exception instead of returning an error), but it made think about
how to handle the errors properly in this code. The "let it crash"
philosophy doesn't really work here, because we need to produce a
meaningful error message to the user and the stack trace is not a
meaningful message to them. I was thinking something like this:

upload_trace_record_file2(Host, Usr, Pwd, RemDir, NetTraceRef) ->
    try
        {sftp_client, {ok, Pid}} = {sftp_client,
sftp_client:open(Host, ?SFTP_PORT, Usr, Pwd)},
....
        {sftp_client, ok} = {sftp_client, sftp_client:send(Pid,
TRFile, RemTRFile)},
        sftp_client:close(Pid),
        file:delete(TRFile)
   catch
        error:{badmatch, {sftp_client, Reason}} ->
	    {error, sftp_client:format_error(Reason)};
        error:{badmatch, {exml, _}} ->
                  {error, bad_xml_file}
    end.

update_trace_record_file(TRFile, NetTraceRef) ->
    {exml, {ok, ReadExml}} = {exml, exml:read_file(TRFile, [{space,
normalize}])},
    {traceCollecFile, Attributes, ChildList} = ReadExml,
...
    file:write_file(TmpTRFile, TraceText),
    TmpTRFile.

but it looks somewhat ugly. Three "assignments" and function calls are
hidden away in tuples, so it's a little hard to read, even though the
rest of the code is simpler. Do you have any other ideas?



More information about the erlang-questions mailing list