-define(tMessageType_CALL, 1).
-define(tMessageType_REPLY, 2).
-define(tMessageType_EXCEPTION, 3).
+
+% TApplicationException
+-define(TApplicationException_Structure,
+ {struct, [{1, string},
+ {2, i32}]}).
+
+-record('TApplicationException', {message, type}).
+
+-define(TApplicationException_UNKNOWN, 0).
+-define(TApplicationException_UNKNOWN_METHOD, 1).
+-define(TApplicationException_INVALID_MESSAGE_TYPE, 2).
+-define(TApplicationException_WRONG_METHOD_NAME, 3).
+-define(TApplicationException_BAD_SEQUENCE_ID, 4).
+-define(TApplicationException_MISSING_RESULT, 5).
+
% configuration parameters similar to those in the config file specified
% on the command line. can be fetched with gas:get_env
{env, [
- {term_width, 110},
- {force_one_line, false},
- {omit_fmt, ["thrift ~p:new(~s) = ~s"]},
- {gen_server_messages, true},
- {show_pid, true},
- {lookup, false} % DNS
+ % If an error/crash occurs during processing of a function,
+ % should the TApplicationException serialized back to the client
+ % include the erlang backtrace?
+ {exceptions_include_traces, true}
]},
% The Module and Args used to start this application.
throw:Exception when is_tuple(Exception), size(Exception) > 0 ->
error_logger:warning_msg("~p threw exception: ~p~n", [Function, Exception]),
handle_exception(State, Function, Exception),
- ok % we still want to accept more requests from this client
+ ok; % we still want to accept more requests from this client
+ error:Error ->
+ ok = handle_error(State, Function, Error)
end.
handle_success(State = #state{out_protocol = OProto,
ok = send_reply(OProto, Function, ?tMessageType_REPLY, {ReplySpec, ExceptionTuple})
end.
+%%
+% Called when an exception has been explicitly thrown by the service, but it was
+% not one of the exceptions that was defined for the function.
+%%
handle_unknown_exception(State, Function, Exception) ->
- io:format("Unknown exception!~n"),
- ok.
+ handle_error(State, Function, {exception_not_declared_as_thrown,
+ Exception}).
+
+handle_error(#state{out_protocol = OProto}, Function, Error) ->
+ Message =
+ case application:get_env(thrift, exceptions_include_traces) of
+ {ok, true} ->
+ lists:flatten(io_lib:format("An error occurred: ~p~n",
+ [{Error, erlang:get_stacktrace()}]));
+ _ ->
+ "An unknown handler error occurred."
+ end,
+ Reply = {?TApplicationException_Structure,
+ #'TApplicationException'{
+ message = Message,
+ type = ?TApplicationException_UNKNOWN}},
+ send_reply(OProto, Function, ?tMessageType_EXCEPTION, Reply).
send_reply(OProto, Function, ReplyMessageType, Reply) ->