[erlang-questions] Mnesia transactions and error handling good practices

Alexander Lamb <>
Wed Jun 11 12:36:18 CEST 2008


Hello,

I read in the Erlang manual about avoiding using too many exceptions  
as well as making the initial assumption that functions work.

I have a practicle (simple) case:

Each time I save a user (a record in a table), I want to archive the  
previous values of that record. For that purpose, I have a users table  
and a users_archive table.

To archive the user, it is simply:

archive_user(User_Id) ->
	F = fun() ->
			case mnesia:read({users,User_Id}) of
				[User]		-> mnesia:write(users_archive,User#users{timestamp =  
calendar:universal_time()},write);
				_Any		-> nothing
			end,
	case mnesia:transaction(F) of
		{atomic, _Result}	-> {ok, archive};
		{aborted, Reason}	-> {error, Reason}
	end.

Now, to insert the new values, I do:

set_user 
(User_Id 
,System_Name 
,Production_Type 
,Email 
,Last_Name,First_Name,Country,User_Status,Save_User_Id,User_Details) ->
	F = fun() ->
			archive_user(User_Id),
			mnesia:write(email,
						 #users{user_id = User_Id, system_name = System_Name,  
production_type = Production_Type, email = Email, last_name =  
Last_Name, first_name = First_Name, country = Country, user_status =  
User_Status, timestamp = calendar:universal_time(), save_user_id =  
Save_User_Id, user_details = User_Details},
						 write)
		end,
	case mnesia:transaction(F) of
		{atomic, _Any}		-> {ok, erlang:binary_to_list(User_Id)};
		{aborted, Reason}	-> {error, Reason}
	end.

Now, obviously, this works as long as the "archive_user" function does  
not return {aborted, Reason}. Indeed, I don't test it.

What is the good practice:

1) Not test "obvious" things (like in this example)
2) Test the response in cascade with case statements
3) Raise an exception in nested function in order to have the outer  
transaction fail

Thanks,

Alex



More information about the erlang-questions mailing list