summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2014-09-10 17:35:53 +0100
committerSimon MacMullen <simon@rabbitmq.com>2014-09-10 17:35:53 +0100
commit54bce9308b67ebfeb77c4090a2ed79aef31ae19b (patch)
tree4a7b4291df0e0821f64749f15ae12bf7f24b9e45
parent4da65790598f6387d99092e7d67745d34d3ab821 (diff)
downloadrabbitmq-server-54bce9308b67ebfeb77c4090a2ed79aef31ae19b.tar.gz
Sensible errors on queue durable / auto_delete inequivalence.
-rw-r--r--src/rabbit_amqqueue.erl18
-rw-r--r--src/rabbit_misc.erl32
2 files changed, 31 insertions, 19 deletions
diff --git a/src/rabbit_amqqueue.erl b/src/rabbit_amqqueue.erl
index 692179fc..5bd93ea2 100644
--- a/src/rabbit_amqqueue.erl
+++ b/src/rabbit_amqqueue.erl
@@ -405,16 +405,14 @@ with_or_die(Name, F) ->
({absent, Q}) -> rabbit_misc:absent(Q)
end).
-assert_equivalence(#amqqueue{durable = Durable,
- auto_delete = AutoDelete} = Q,
- Durable, AutoDelete, RequiredArgs, Owner) ->
- assert_args_equivalence(Q, RequiredArgs),
- check_exclusive_access(Q, Owner, strict);
-assert_equivalence(#amqqueue{name = QueueName},
- _Durable, _AutoDelete, _RequiredArgs, _Owner) ->
- rabbit_misc:protocol_error(
- precondition_failed, "parameters for ~s not equivalent",
- [rabbit_misc:rs(QueueName)]).
+assert_equivalence(#amqqueue{name = QName,
+ durable = Durable,
+ auto_delete = AD} = Q,
+ Durable1, AD1, Args1, Owner) ->
+ rabbit_misc:assert_field_equivalence(Durable, Durable1, QName, durable),
+ rabbit_misc:assert_field_equivalence(AD, AD1, QName, auto_delete),
+ assert_args_equivalence(Q, Args1),
+ check_exclusive_access(Q, Owner, strict).
check_exclusive_access(Q, Owner) -> check_exclusive_access(Q, Owner, lax).
diff --git a/src/rabbit_misc.erl b/src/rabbit_misc.erl
index c4148bbf..bd8ba42e 100644
--- a/src/rabbit_misc.erl
+++ b/src/rabbit_misc.erl
@@ -22,7 +22,7 @@
-export([die/1, frame_error/2, amqp_error/4, quit/1,
protocol_error/3, protocol_error/4, protocol_error/1]).
-export([not_found/1, absent/1]).
--export([type_class/1, assert_args_equivalence/4]).
+-export([type_class/1, assert_args_equivalence/4, assert_field_equivalence/4]).
-export([dirty_read/1]).
-export([table_lookup/2, set_table_value/4]).
-export([r/3, r/2, r_arg/4, rs/1]).
@@ -125,6 +125,9 @@
rabbit_framing:amqp_table(),
rabbit_types:r(any()), [binary()]) ->
'ok' | rabbit_types:connection_exit()).
+-spec(assert_field_equivalence/4 ::
+ (any(), any(), rabbit_types:r(any()), atom()) ->
+ 'ok' | rabbit_types:connection_exit()).
-spec(dirty_read/1 ::
({atom(), any()}) -> rabbit_types:ok_or_error2(any(), 'not_found')).
-spec(table_lookup/2 ::
@@ -316,11 +319,6 @@ assert_args_equivalence(Orig, New, Name, Keys) ->
assert_args_equivalence1(Orig, New, Name, Key) ->
{Orig1, New1} = {table_lookup(Orig, Key), table_lookup(New, Key)},
- FailureFun = fun () ->
- protocol_error(precondition_failed, "inequivalent arg '~s'"
- "for ~s: received ~s but current is ~s",
- [Key, rs(Name), val(New1), val(Orig1)])
- end,
case {Orig1, New1} of
{Same, Same} ->
ok;
@@ -328,12 +326,22 @@ assert_args_equivalence1(Orig, New, Name, Key) ->
case type_class(OrigType) == type_class(NewType) andalso
OrigVal == NewVal of
true -> ok;
- false -> FailureFun()
+ false -> assert_field_equivalence(OrigVal, NewVal, Name, Key)
end;
{_, _} ->
- FailureFun()
+ assert_field_equivalence(Orig, New, Name, Key)
end.
+assert_field_equivalence(_Orig, _Orig, _Name, _Key) ->
+ ok;
+assert_field_equivalence(Orig, New, Name, Key) ->
+ equivalence_fail(Orig, New, Name, Key).
+
+equivalence_fail(Orig, New, Name, Key) ->
+ protocol_error(precondition_failed, "inequivalent arg '~s' "
+ "for ~s: received ~s but current is ~s",
+ [Key, rs(Name), val(New), val(Orig)]).
+
val(undefined) ->
"none";
val({Type, Value}) ->
@@ -341,7 +349,13 @@ val({Type, Value}) ->
true -> "~s";
false -> "~w"
end,
- format("the value '" ++ ValFmt ++ "' of type '~s'", [Value, Type]).
+ format("the value '" ++ ValFmt ++ "' of type '~s'", [Value, Type]);
+val(Value) ->
+ ValFmt = case is_binary(Value) of
+ true -> "~s";
+ false -> "~w"
+ end,
+ format(ValFmt, [Value]).
%% Normally we'd call mnesia:dirty_read/1 here, but that is quite
%% expensive due to general mnesia overheads (figuring out table types