Skip to content

Commit 03ab566

Browse files
author
Matthew Sackman
committed
Merging bug 22935 into default
2 parents ebdd43e + e9c3652 commit 03ab566

File tree

2 files changed

+40
-19
lines changed

2 files changed

+40
-19
lines changed

src/rabbit_channel.erl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,9 @@ binding_action(Fun, ExchangeNameBin, QueueNameBin, RoutingKey, Arguments,
911911
check_read_permitted(ExchangeName, State),
912912
case Fun(ExchangeName, QueueName, ActualRoutingKey, Arguments,
913913
fun (_X, Q) ->
914-
rabbit_amqqueue:check_exclusive_access(Q, ReaderPid)
914+
try rabbit_amqqueue:check_exclusive_access(Q, ReaderPid)
915+
catch exit:Reason -> {error, Reason}
916+
end
915917
end) of
916918
{error, exchange_not_found} ->
917919
rabbit_misc:not_found(ExchangeName);
@@ -926,6 +928,10 @@ binding_action(Fun, ExchangeNameBin, QueueNameBin, RoutingKey, Arguments,
926928
not_found, "no binding ~s between ~s and ~s",
927929
[RoutingKey, rabbit_misc:rs(ExchangeName),
928930
rabbit_misc:rs(QueueName)]);
931+
%% When check_exclusive_access exits with a protocol error this gets
932+
%% wrapped by mnesia. Unwrap it and exit again.
933+
{error, #amqp_error{} = Error} ->
934+
exit(Error);
929935
ok -> return_ok(State, NoWait, ReturnMethod)
930936
end.
931937

src/rabbit_exchange.erl

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@
6464
-type(bind_res() :: rabbit_types:ok_or_error('queue_not_found' |
6565
'exchange_not_found' |
6666
'exchange_and_queue_not_found')).
67-
-type(inner_fun() :: fun((rabbit_types:exchange(), queue()) -> any())).
67+
-type(inner_fun() ::
68+
fun((rabbit_types:exchange(), queue()) ->
69+
rabbit_types:ok_or_error(rabbit_types:amqp_error()))).
6870

6971
-spec(recover/0 :: () -> 'ok').
7072
-spec(declare/5 ::
@@ -427,23 +429,27 @@ add_binding(ExchangeName, QueueName, RoutingKey, Arguments, InnerFun) ->
427429
%% this argument is used to check queue exclusivity;
428430
%% in general, we want to fail on that in preference to
429431
%% anything else
430-
InnerFun(X, Q),
431-
case mnesia:read({rabbit_route, B}) of
432-
[] ->
433-
sync_binding(B,
434-
X#exchange.durable andalso
435-
Q#amqqueue.durable,
436-
fun mnesia:write/3),
437-
{new, X, B};
438-
[_R] ->
439-
{existing, X, B}
432+
case InnerFun(X, Q) of
433+
ok ->
434+
case mnesia:read({rabbit_route, B}) of
435+
[] ->
436+
ok = sync_binding(B,
437+
X#exchange.durable andalso
438+
Q#amqqueue.durable,
439+
fun mnesia:write/3),
440+
{new, X, B};
441+
[_R] ->
442+
{existing, X, B}
443+
end;
444+
{error, _} = E ->
445+
E
440446
end
441447
end) of
442448
{new, Exchange = #exchange{ type = Type }, Binding} ->
443449
(type_to_module(Type)):add_binding(Exchange, Binding);
444450
{existing, _, _} ->
445451
ok;
446-
Err = {error, _} ->
452+
{error, _} = Err ->
447453
Err
448454
end.
449455

@@ -453,14 +459,23 @@ delete_binding(ExchangeName, QueueName, RoutingKey, Arguments, InnerFun) ->
453459
fun (X, Q, B) ->
454460
case mnesia:match_object(rabbit_route, #route{binding = B},
455461
write) of
456-
[] -> {error, binding_not_found};
457-
_ -> InnerFun(X, Q),
458-
ok = sync_binding(B, Q#amqqueue.durable,
459-
fun mnesia:delete_object/3),
460-
{maybe_auto_delete(X), B}
462+
[] ->
463+
{error, binding_not_found};
464+
_ ->
465+
case InnerFun(X, Q) of
466+
ok ->
467+
ok =
468+
sync_binding(B,
469+
X#exchange.durable andalso
470+
Q#amqqueue.durable,
471+
fun mnesia:delete_object/3),
472+
{maybe_auto_delete(X), B};
473+
{error, _} = E ->
474+
E
475+
end
461476
end
462477
end) of
463-
Err = {error, _} ->
478+
{error, _} = Err ->
464479
Err;
465480
{{IsDeleted, X = #exchange{ type = Type }}, B} ->
466481
Module = type_to_module(Type),

0 commit comments

Comments
 (0)