summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvaro Videla <videlalvaro@gmail.com>2013-12-18 19:22:38 +0100
committerAlvaro Videla <videlalvaro@gmail.com>2013-12-18 19:22:38 +0100
commit05830cdb25cae9910c61d54ed94dfc25651c5a8b (patch)
tree381bd2f808f33cc2c53bf49813cbe4834c5597d6
parent5e9bb2c4177f1c0c2ad3ec8b25df7a397be175c7 (diff)
downloadrabbitmq-server-05830cdb25cae9910c61d54ed94dfc25651c5a8b.tar.gz
handle interceptor exceptions at the channel level.
-rw-r--r--src/rabbit_channel.erl35
-rw-r--r--src/rabbit_channel_interceptor.erl19
2 files changed, 29 insertions, 25 deletions
diff --git a/src/rabbit_channel.erl b/src/rabbit_channel.erl
index ff6bbb11..ebac2e6a 100644
--- a/src/rabbit_channel.erl
+++ b/src/rabbit_channel.erl
@@ -273,19 +273,28 @@ handle_cast({method, Method, Content, Flow},
noflow -> ok
end,
%% handle MRDQ before calling handle method
- Method2 = handle_expand_shortcuts(Method, State),
- try handle_method(Method2, Content, State) of
- {reply, Reply, NewState} ->
- ok = send(Reply, NewState),
- noreply(NewState);
- {noreply, NewState} ->
- noreply(NewState);
- stop ->
- {stop, normal, State}
+ M = handle_expand_shortcuts(Method, State),
+ try rabbit_channel_interceptor:intercept_method(M) of
+ {ok, Method2} ->
+ try handle_method(Method2, Content, State) of
+ {reply, Reply, NewState} ->
+ ok = send(Reply, NewState),
+ noreply(NewState);
+ {noreply, NewState} ->
+ noreply(NewState);
+ stop ->
+ {stop, normal, State}
+ catch
+ exit:Reason = #amqp_error{} ->
+ handle_method_exception(Reason, Method2, State);
+ _:Reason ->
+ {stop, {Reason, erlang:get_stacktrace()}, State}
+ end;
+ {error, Reason} ->
+ rabbit_misc:protocol_error(internal_error, Reason, [])
catch
exit:Reason = #amqp_error{} ->
- MethodName = rabbit_misc:method_record_type(Method2),
- handle_exception(Reason#amqp_error{method = MethodName}, State);
+ handle_method_exception(Reason, Method, State);
_:Reason ->
{stop, {Reason, erlang:get_stacktrace()}, State}
end;
@@ -429,6 +438,10 @@ send(_Command, #ch{state = closing}) ->
send(Command, #ch{writer_pid = WriterPid}) ->
ok = rabbit_writer:send_command(WriterPid, Command).
+handle_method_exception(Reason, Method, State) ->
+ MethodName = rabbit_misc:method_record_type(Method),
+ handle_exception(Reason#amqp_error{method = MethodName}, State).
+
handle_exception(Reason, State = #ch{protocol = Protocol,
channel = Channel,
writer_pid = WriterPid,
diff --git a/src/rabbit_channel_interceptor.erl b/src/rabbit_channel_interceptor.erl
index 1b0c01f2..48b24082 100644
--- a/src/rabbit_channel_interceptor.erl
+++ b/src/rabbit_channel_interceptor.erl
@@ -54,21 +54,12 @@ intercept_method(M) ->
intercept_method(M, select(M)).
intercept_method(M, []) ->
- M;
+ {ok, M};
intercept_method(M, [I]) ->
- case I:intercept(M) of
- {ok, M2} ->
- M2;
- {error, Reason} ->
- rabbit_misc:protocol_error(
- internal_error, "~s",
- [Reason])
- end;
-intercept_method(M, _) ->
- rabbit_misc:protocol_error(
- internal_error,
- "More than one interceptor defined for method: ~p",
- [rabbit_misc:method_record_type(M)]).
+ I:intercept(M);
+intercept_method(M, Is) ->
+ {error, rabbit_misc:format("More than one interceptor for method: ~p - ~p",
+ [rabbit_misc:method_record_type(M)], Is)}.
%% select the interceptors that apply to intercept_method().
select(Method) ->