If you code nothing for error cases, letting the system generating a run time error you get at least 3 advantages:
the code is smaller, easier to read, focused on the function to realize.
in error cases, the system will raise an error compliant with the OTP standard, you will benefit for free of all OTP mechanisms to handle the situation at the appropriate level.
you automatically avoid the "lasagna" error detection syndrome, where many code layers track the same error case.
Now you can concentrate on the error management: where will you handle the errors. Erlang offers the classical way with the try and catch statements, and has a more idiomatic way with the OTP supervision tree and the link and monitor mechanism.
In a few words you have the control on the consequence of one process crash (which processes will crash with it, which processes will be informed) and sophisticated means to restart them.
It is important to keep in mind that in erlang you generally starts many small processes which have a very limited role an responsibility, and in this case, letting them crash and restart really makes sense.
I am a fan of the learnyousomeerlang web site where you will find 3 chapters related to the error management:
- Errors and Exceptions
- Errors and Processes
- Who Supervises The Supervisors?