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

Jon Watte <>
Thu Nov 3 20:05:55 CET 2011


Two things I can think of:

try / after is useful if you have side effects you need to unwind.

Matching on {ok, ...} is useful when all you really want to do is generate
an error -- if something doesn't go as you expect, let it crash, and let a
higher level deal with reporting the error to the client.

Sincerely,

jw


--
Americans might object: there is no way we would sacrifice our living
standards for the benefit of people in the rest of the world. Nevertheless,
whether we get there willingly or not, we shall soon have lower consumption
rates, because our present rates are unsustainable.



On Thu, Nov 3, 2011 at 6:08 AM, Attila Rajmund Nohl <
> wrote:

> 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?
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20111103/e8f515ff/attachment.html>


More information about the erlang-questions mailing list