summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthew Sackman <matthew@rabbitmq.com>2010-07-08 17:23:17 +0100
committerMatthew Sackman <matthew@rabbitmq.com>2010-07-08 17:23:17 +0100
commit03ab56687cd0f959c5a47906430a6e1182055f05 (patch)
tree2e5cc475838ae5c46929c78cabdd101269af086d /src
parentebdd43e4c7c0fc19be9e99e71ae6b6a71a44a771 (diff)
parente9c3652cbac26a80254668dbe8aeec813b3f13e6 (diff)
downloadrabbitmq-server-git-03ab56687cd0f959c5a47906430a6e1182055f05.tar.gz
Merging bug 22935 into default
Diffstat (limited to 'src')
-rw-r--r--src/rabbit_channel.erl8
-rw-r--r--src/rabbit_exchange.erl51
2 files changed, 40 insertions, 19 deletions
diff --git a/src/rabbit_channel.erl b/src/rabbit_channel.erl
index da8225debc..9a02e2bd13 100644
--- a/src/rabbit_channel.erl
+++ b/src/rabbit_channel.erl
@@ -911,7 +911,9 @@ binding_action(Fun, ExchangeNameBin, QueueNameBin, RoutingKey, Arguments,
check_read_permitted(ExchangeName, State),
case Fun(ExchangeName, QueueName, ActualRoutingKey, Arguments,
fun (_X, Q) ->
- rabbit_amqqueue:check_exclusive_access(Q, ReaderPid)
+ try rabbit_amqqueue:check_exclusive_access(Q, ReaderPid)
+ catch exit:Reason -> {error, Reason}
+ end
end) of
{error, exchange_not_found} ->
rabbit_misc:not_found(ExchangeName);
@@ -926,6 +928,10 @@ binding_action(Fun, ExchangeNameBin, QueueNameBin, RoutingKey, Arguments,
not_found, "no binding ~s between ~s and ~s",
[RoutingKey, rabbit_misc:rs(ExchangeName),
rabbit_misc:rs(QueueName)]);
+ %% When check_exclusive_access exits with a protocol error this gets
+ %% wrapped by mnesia. Unwrap it and exit again.
+ {error, #amqp_error{} = Error} ->
+ exit(Error);
ok -> return_ok(State, NoWait, ReturnMethod)
end.
diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl
index 822c164d57..d91ebe9ba9 100644
--- a/src/rabbit_exchange.erl
+++ b/src/rabbit_exchange.erl
@@ -64,7 +64,9 @@
-type(bind_res() :: rabbit_types:ok_or_error('queue_not_found' |
'exchange_not_found' |
'exchange_and_queue_not_found')).
--type(inner_fun() :: fun((rabbit_types:exchange(), queue()) -> any())).
+-type(inner_fun() ::
+ fun((rabbit_types:exchange(), queue()) ->
+ rabbit_types:ok_or_error(rabbit_types:amqp_error()))).
-spec(recover/0 :: () -> 'ok').
-spec(declare/5 ::
@@ -427,23 +429,27 @@ add_binding(ExchangeName, QueueName, RoutingKey, Arguments, InnerFun) ->
%% this argument is used to check queue exclusivity;
%% in general, we want to fail on that in preference to
%% anything else
- InnerFun(X, Q),
- case mnesia:read({rabbit_route, B}) of
- [] ->
- sync_binding(B,
- X#exchange.durable andalso
- Q#amqqueue.durable,
- fun mnesia:write/3),
- {new, X, B};
- [_R] ->
- {existing, X, B}
+ case InnerFun(X, Q) of
+ ok ->
+ case mnesia:read({rabbit_route, B}) of
+ [] ->
+ ok = sync_binding(B,
+ X#exchange.durable andalso
+ Q#amqqueue.durable,
+ fun mnesia:write/3),
+ {new, X, B};
+ [_R] ->
+ {existing, X, B}
+ end;
+ {error, _} = E ->
+ E
end
end) of
{new, Exchange = #exchange{ type = Type }, Binding} ->
(type_to_module(Type)):add_binding(Exchange, Binding);
{existing, _, _} ->
ok;
- Err = {error, _} ->
+ {error, _} = Err ->
Err
end.
@@ -453,14 +459,23 @@ delete_binding(ExchangeName, QueueName, RoutingKey, Arguments, InnerFun) ->
fun (X, Q, B) ->
case mnesia:match_object(rabbit_route, #route{binding = B},
write) of
- [] -> {error, binding_not_found};
- _ -> InnerFun(X, Q),
- ok = sync_binding(B, Q#amqqueue.durable,
- fun mnesia:delete_object/3),
- {maybe_auto_delete(X), B}
+ [] ->
+ {error, binding_not_found};
+ _ ->
+ case InnerFun(X, Q) of
+ ok ->
+ ok =
+ sync_binding(B,
+ X#exchange.durable andalso
+ Q#amqqueue.durable,
+ fun mnesia:delete_object/3),
+ {maybe_auto_delete(X), B};
+ {error, _} = E ->
+ E
+ end
end
end) of
- Err = {error, _} ->
+ {error, _} = Err ->
Err;
{{IsDeleted, X = #exchange{ type = Type }}, B} ->
Module = type_to_module(Type),