(I want to cite another question as a reference: How do I elegantly check many conditions in Erlang?)
The generic form of "success case code separated from error handling" seems to be:
try
ok = do_x(),
...
ok = do_y()
catch
error:{badmatch, x_failure} -> do_something1();
...
error:{badmatch, y_failure} -> do_something2();
How does one use this pattern when the functions in the try clause do something with a side effect, such as write a file, sent a network packet, write a line into a database, etc? Is there a generic pattern for a "rollback" in the catch clause? Example:
try
%How to make this whole block a transaction?
ok = step_1_write_file(),
ok = step_2_write_database(),
ok = step_3_send_packet(),
...
catch
error:{badmatch, database_failure} -> clean_up_step_1() %delete file?
error:{badmatch, sendpacket_failure} -> clean_up_step_1_and_2() %??
It seems like the error handling gets onerous, where the cleanup that needs to be performed is dependent on the step in the try
block that failed.
Is there a general programming pattern that treats this as a transaction, whereas the succeeded steps in the try block preceding the failed clause are ``unwound"?