[erlang-questions] Idiomatically handling multiple validation checks

zxq9 <>
Tue Dec 6 10:25:10 CET 2016


On 2016年12月6日 火曜日 10:13:34 Dmytro Lytovchenko wrote:
> For things like web form or input validation and transformation, it is
> often a good idea to make a chain of nested calls.
> 
> Imagine your user submitted a form which you store in Data = #{login="",
> password=""}, you can do something like this:
> 
> try
>     create_session(check_password(check_login(Data)))
> catch throw:{validation_error, E} -> my_report_error(E)
> end,...
> 
> 
> Here each function (check_login, check_password, create_session) takes
> result of the previous function, it can be that same Data, or Data paired
> with some intermediate results if you wish. To signal an error you use
> erlang:throw({validation_error, "my error"}) and it will be caught in the
> catch clause.

That's one way to do it... but most code I've seen that makes heavy use
of `throw` has insane structural issues (either actual bugs, or mental
grenades with C++ style confusing execution).

Basically, what I'm getting at is that `throw` is a keyword oft used in
prayer and curse in Mordor.

Why not return `{error, Reason}` back up the chain of calls? Then the
top-level caller can choose whether to crash on an `{ok, Value}` or
`{error, Reason}` assertion match, or engage in their own insanity with
`throw` .. `catch` and other nonsense.

-Craig

PS: Yes, I generally regard use of `throw` as "nonsense" and won't
apologize for that characterization of this 99% horrible curseword,
no matter how much I may be hurting its feelings.


More information about the erlang-questions mailing list