From 920959a655028e93409572f44535aaf6c5a398d7 Mon Sep 17 00:00:00 2001 From: David Reiss Date: Wed, 11 Jun 2008 00:56:35 +0000 Subject: [PATCH] Handle crashes/errors in the processor by sending back a serialized exception git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@666407 13f79535-47bb-0310-9956-ffa450edef68 --- lib/alterl/include/thrift_constants.hrl | 15 ++++++++++++++ lib/alterl/src/thrift.app.src | 10 ++++----- lib/alterl/src/thrift_processor.erl | 27 ++++++++++++++++++++++--- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/lib/alterl/include/thrift_constants.hrl b/lib/alterl/include/thrift_constants.hrl index 19480610..c9b9cd1f 100644 --- a/lib/alterl/include/thrift_constants.hrl +++ b/lib/alterl/include/thrift_constants.hrl @@ -23,3 +23,18 @@ -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). + diff --git a/lib/alterl/src/thrift.app.src b/lib/alterl/src/thrift.app.src index 79055ca6..681b3eb3 100644 --- a/lib/alterl/src/thrift.app.src +++ b/lib/alterl/src/thrift.app.src @@ -32,12 +32,10 @@ % 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. diff --git a/lib/alterl/src/thrift_processor.erl b/lib/alterl/src/thrift_processor.erl index fa33d3bc..8cc53c30 100644 --- a/lib/alterl/src/thrift_processor.erl +++ b/lib/alterl/src/thrift_processor.erl @@ -55,7 +55,9 @@ handle_function(State = #state{in_protocol = IProto, 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, @@ -111,9 +113,28 @@ handle_exception(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) -> -- 2.17.1