diff options
author | Matthias Radestock <matthias@rabbitmq.com> | 2012-10-24 00:07:12 +0100 |
---|---|---|
committer | Matthias Radestock <matthias@rabbitmq.com> | 2012-10-24 00:07:12 +0100 |
commit | 7a5c2bba14e02c1801ed30e16a5cce889b24d9c7 (patch) | |
tree | ed6c0903a566163232fca21d24ec4eebb1616904 | |
parent | a1681fe2227d2074b3e26fc9dfb1ba2f41219371 (diff) | |
download | rabbitmq-server-7a5c2bba14e02c1801ed30e16a5cce889b24d9c7.tar.gz |
better error messages for 'absent' queues on declaration
- change amqqueue:internal_declare to return {absent, Q} instead
of 'not_found'
- let this ripple through amqqueue_process:declare, stopping with
{absent, Q} instead
- that in in turn will end up in in amqqueue:declare/5. Instead of
inovking misc:not_found(QName), which was EXITing, we make {absent,
Q} part of the API.
- at the call site in the channel we handle the new {absent, Q} case
and produce a nice error message.
-rw-r--r-- | src/rabbit_amqqueue.erl | 22 | ||||
-rw-r--r-- | src/rabbit_amqqueue_process.erl | 10 | ||||
-rw-r--r-- | src/rabbit_channel.erl | 13 |
3 files changed, 27 insertions, 18 deletions
diff --git a/src/rabbit_amqqueue.erl b/src/rabbit_amqqueue.erl index 6ad85b24..8ab9bc87 100644 --- a/src/rabbit_amqqueue.erl +++ b/src/rabbit_amqqueue.erl @@ -61,18 +61,19 @@ -type(ok_or_errors() :: 'ok' | {'error', [{'error' | 'exit' | 'throw', any()}]}). -type(routing_result() :: 'routed' | 'unroutable'). --type(queue_or_not_found() :: rabbit_types:amqqueue() | 'not_found'). +-type(queue_or_absent() :: rabbit_types:amqqueue() | + {'absent', rabbit_types:amqqueue()}). -spec(start/0 :: () -> [name()]). -spec(stop/0 :: () -> 'ok'). -spec(declare/5 :: (name(), boolean(), boolean(), rabbit_framing:amqp_table(), rabbit_types:maybe(pid())) - -> {'new' | 'existing', rabbit_types:amqqueue()} | + -> {'new' | 'existing' | 'absent', rabbit_types:amqqueue()} | rabbit_types:channel_exit()). -spec(internal_declare/2 :: (rabbit_types:amqqueue(), boolean()) - -> queue_or_not_found() | rabbit_misc:thunk(queue_or_not_found())). + -> queue_or_absent() | rabbit_misc:thunk(queue_or_absent())). -spec(update/2 :: (name(), fun((rabbit_types:amqqueue()) -> rabbit_types:amqqueue())) -> 'ok'). @@ -223,10 +224,7 @@ declare(QueueName, Durable, AutoDelete, Args, Owner) -> gm_pids = []}), {Node, _MNodes} = rabbit_mirror_queue_misc:suggested_queue_nodes(Q0), Q1 = start_queue_process(Node, Q0), - case gen_server2:call(Q1#amqqueue.pid, {init, false}, infinity) of - not_found -> rabbit_misc:not_found(QueueName); - Q2 -> Q2 - end. + gen_server2:call(Q1#amqqueue.pid, {init, false}, infinity). internal_declare(Q, true) -> rabbit_misc:execute_mnesia_tx_with_tail( @@ -237,12 +235,12 @@ internal_declare(Q = #amqqueue{name = QueueName}, false) -> case mnesia:wread({rabbit_queue, QueueName}) of [] -> case mnesia:read({rabbit_durable_queue, QueueName}) of - [] -> Q1 = rabbit_policy:set(Q), - ok = store_queue(Q1), - B = add_default_binding(Q1), - fun () -> B(), Q1 end; + [] -> Q1 = rabbit_policy:set(Q), + ok = store_queue(Q1), + B = add_default_binding(Q1), + fun () -> B(), Q1 end; %% Q exists on stopped node - [_] -> rabbit_misc:const(not_found) + [Q1] -> rabbit_misc:const({absent, Q1}) end; [ExistingQ = #amqqueue{pid = QPid}] -> case rabbit_misc:is_process_alive(QPid) of diff --git a/src/rabbit_amqqueue_process.erl b/src/rabbit_amqqueue_process.erl index 68f95778..40240cb1 100644 --- a/src/rabbit_amqqueue_process.erl +++ b/src/rabbit_amqqueue_process.erl @@ -196,9 +196,7 @@ declare(Recover, From, State = #q{q = Q, backing_queue = BQ, backing_queue_state = undefined}) -> case rabbit_amqqueue:internal_declare(Q, Recover) of - not_found -> - {stop, normal, not_found, State}; - Q1 -> + #amqqueue{} = Q1 -> case matches(Recover, Q, Q1) of true -> gen_server2:reply(From, {new, Q}), @@ -216,8 +214,10 @@ declare(Recover, From, State = #q{q = Q, noreply(State1); false -> {stop, normal, {existing, Q1}, State} - end - end. + end; + Err -> + {stop, normal, Err, State} + end. matches(true, Q, Q) -> true; matches(true, _Q, _Q1) -> false; diff --git a/src/rabbit_channel.erl b/src/rabbit_channel.erl index 0d13312b..276ad38f 100644 --- a/src/rabbit_channel.erl +++ b/src/rabbit_channel.erl @@ -423,6 +423,15 @@ precondition_failed(Format) -> precondition_failed(Format, []). precondition_failed(Format, Params) -> rabbit_misc:protocol_error(precondition_failed, Format, Params). +absent(#amqqueue{name = QueueName, pid = QPid, durable = true}) -> + %% The assertion of durability is mainly there because we mention + %% durability in the error message. That way we will hopefully + %% notice if at some future point our logic changes s.t. we get + %% here with non-durable queues. + rabbit_misc:protocol_error( + not_found, "home node '~s' of durable ~s is down or inaccessible", + [node(QPid), rabbit_misc:rs(QueueName)]). + return_queue_declare_ok(#resource{name = ActualName}, NoWait, MessageCount, ConsumerCount, State) -> return_ok(State#ch{most_recently_declared_queue = ActualName}, NoWait, @@ -960,7 +969,9 @@ handle_method(#'queue.declare'{queue = QueueNameBin, {existing, _Q} -> %% must have been created between the stat and the %% declare. Loop around again. - handle_method(Declare, none, State) + handle_method(Declare, none, State); + {absent, Q} -> + absent(Q) end end; |