[erlang-questions] feedback on my solutions to programming erlang second edition

Loïc Hoguin essen@REDACTED
Mon Aug 17 13:14:39 CEST 2015


On 08/17/2015 01:07 PM, Garrett Smith wrote:
> On Mon, Aug 17, 2015 at 5:54 AM, Loïc Hoguin <essen@REDACTED> wrote:
>> On 08/17/2015 12:38 PM, Garrett Smith wrote:
>>>
>>> On Mon, Aug 17, 2015 at 3:15 AM, Loïc Hoguin <essen@REDACTED> wrote:
>>>> I find that returning {error, ErrorForPrograms, ErrorForHumans} is a much
>>>> saner solution because the first error value helps the program know what
>>>> kind of error it is, and the second error value says exactly what
>>>> happened
>>>> for the human who is debugging (locally or when calling an HTTP service,
>>>> as
>>>> this error can also be sent as response).
>>>>
>>>> This has the additional benefit that the ErrorForHumans value also serves
>>>> as
>>>> inlined documentation.
>>>
>>>
>>> I wouldn't make this as a general recommendation for folks. It might
>>> make sense in a particular application.
>>>
>>> My rule is that an error should convey the minimal amount of
>>> information to identify and fix a problem. In a lot of cases that's an
>>> internal problem that needs some rethinking, additional logic, etc.
>>> but once handled properly shouldn't surface to the user. Problems that
>>> can legitimately be handled by a user, including some user readable
>>> content in the original message seems fine. As for i18n, it's common
>>> to translate the original message, usually in English, when presented
>>> to the user.
>>
>> The error message I am talking about is *not* for end users (i.e. your mom
>> on Facebook) but for *developers* (i.e. Facebook engineers) who have to look
>> at the logs and figure out what went wrong.
>
> Yeah, my Mom hates those cryptic Erlang term errors :)
>
> For me as a programmer (though Facebook would never hire me so this is
> speculative) I will try to tie the error to it's source like this:
>
> open_user_config(Name) ->
>     case open_file(Name) of
>       {ok, File} -> File;
>       {error, Err} -> error({open_user_config, Name, Err})
>    end.
>
> which will manifest as, e.g.:
>
> {'EXIT',{{open_user_config,"/etc/user.config",enoent}, ...}
>
> which is pretty easy to follow IMO.

Yes, though for errors as simple as this the benefits are not as obvious 
as errors where the answer is deep inside a hundred pages document. :-)

Actually there's different kinds of errors, and the one kind that 
benefits the most from this would be programmer error when calling the 
function/service/.. In other words errors that say "YOU SHALL NOT PASS 
because of reasons X Y Z."

> I imagine this is what you're talking about, the difference being in
> the use of atoms vs strings as "user descriptors", or no?

I use atoms because they're very cheap *but* if I had to have some 
variables bundled into it I would use a tuple like you do.

-- 
Loïc Hoguin
http://ninenines.eu
Author of The Erlanger Playbook,
A book about software development using Erlang



More information about the erlang-questions mailing list