[erlang-questions] Best practices for handling invalid / unexpected messages

Vance Shipley <>
Sat May 14 07:40:50 CEST 2011


Ciprian,

If it's an API, either public or private, I find the sensible thing
to do is to have the caller fail with `badarg' just as they would do
when calling a function call with the wrong arguments.

Using an API module:

	%% @spec (Pid::pid()) -> term()
	%%
	foo(Pid) when is_pid(Pid) ->
		case gen_server:call(Pid, foo) of
			{ok, Value} ->
				Value;
			{error, Reason} ->
				exit(Reason)
		end.

The callback would be:

	handle_call(foo, From, State) ->
		...
		{reply, {ok, Foo}, State};
	handle_call(_, From, State) ->
		{reply, {error, badarg}, State}.


When the client calls gen_server:call/2 directly:

	handle_call(foo, From, State) ->
		...
		{reply, Foo, State};
	handle_call(_, {_, Pid}, State) ->
		{reply, exit(Pid, badarg), State}.


On Fri, May 13, 2011 at 11:34:11PM +0300, Ciprian Dorin Craciun wrote:
}      For example it would have been nice to have a return value like
}  `{error, Reason, NewState}` from callbacks like `handle_call`, etc.;
}  which depending on the running environment either "dispatches"
}  `{reply, {error, Reason}, NewState}`, or `{stop, {error, Reason},
}  NewState}`. But as such a solution doesn't exist I could just create
}  three generic functions like `handle_call_error (Reason, NewState)`
}  that is called from within `handle_call` in a tail position, thus
}  achieving the same outcome.
}  
}      Any other ideas?

-- 
	-Vance



More information about the erlang-questions mailing list