Merge pull request #11412 from rabbitmq/link-error
Prefer link error over session error
This commit is contained in:
commit
b9f387b988
|
|
@ -2305,12 +2305,8 @@ incoming_link_transfer(
|
|||
"delivery_tag=~p, delivery_id=~p, reason=~p",
|
||||
[DeliveryTag, DeliveryId, Reason])
|
||||
end;
|
||||
{error, not_found, XName} ->
|
||||
{error, #'v1_0.error'{} = Err} ->
|
||||
Disposition = released(DeliveryId),
|
||||
Description = unicode:characters_to_binary("no " ++ rabbit_misc:rs(XName)),
|
||||
Err = #'v1_0.error'{
|
||||
condition = ?V_1_0_AMQP_ERROR_NOT_FOUND,
|
||||
description = {utf8, Description}},
|
||||
Detach = detach(HandleInt, Link0, Err),
|
||||
{error, [Disposition, Detach]}
|
||||
end.
|
||||
|
|
@ -2322,7 +2318,7 @@ lookup_target(#resource{} = XName, LinkRKey, Mc, _, _, PermCache) ->
|
|||
{ok, X} ->
|
||||
lookup_routing_key(X, LinkRKey, Mc, PermCache);
|
||||
{error, not_found} ->
|
||||
{error, not_found, XName}
|
||||
{error, error_not_found(XName)}
|
||||
end;
|
||||
lookup_target(to, to, Mc, Vhost, User, PermCache0) ->
|
||||
case mc:property(to, Mc) of
|
||||
|
|
@ -2336,19 +2332,19 @@ lookup_target(to, to, Mc, Vhost, User, PermCache0) ->
|
|||
check_internal_exchange(X),
|
||||
lookup_routing_key(X, RKey, Mc, PermCache);
|
||||
{error, not_found} ->
|
||||
{error, not_found, XName}
|
||||
{error, error_not_found(XName)}
|
||||
end;
|
||||
{error, bad_address} ->
|
||||
protocol_error(
|
||||
?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
|
||||
"bad 'to' address string: ~ts",
|
||||
[String])
|
||||
{error,
|
||||
#'v1_0.error'{
|
||||
condition = ?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
|
||||
description = {utf8, <<"bad 'to' address string: ", String/binary>>}}}
|
||||
end;
|
||||
undefined ->
|
||||
protocol_error(
|
||||
?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
|
||||
"anonymous terminus requires 'to' address to be set",
|
||||
[])
|
||||
{error,
|
||||
#'v1_0.error'{
|
||||
condition = ?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
|
||||
description = {utf8, <<"anonymous terminus requires 'to' address to be set">>}}}
|
||||
end.
|
||||
|
||||
lookup_routing_key(X = #exchange{name = #resource{name = XNameBin}},
|
||||
|
|
@ -2430,7 +2426,7 @@ maybe_grant_mgmt_link_credit(Credit, _, _) ->
|
|||
{ok, rabbit_amqqueue:name(), permission_cache(), topic_permission_cache()} |
|
||||
{error, term()}.
|
||||
ensure_source(#'v1_0.source'{dynamic = true}, _, _, _, _) ->
|
||||
not_implemented("Dynamic sources not supported");
|
||||
exit_not_implemented("Dynamic sources not supported");
|
||||
ensure_source(#'v1_0.source'{address = Address,
|
||||
durable = Durable},
|
||||
Vhost, User, PermCache, TopicPermCache) ->
|
||||
|
|
@ -2504,7 +2500,7 @@ ensure_source_v2(Address, _, _, _) ->
|
|||
permission_cache()} |
|
||||
{error, term()}.
|
||||
ensure_target(#'v1_0.target'{dynamic = true}, _, _, _) ->
|
||||
not_implemented("Dynamic targets not supported");
|
||||
exit_not_implemented("Dynamic targets not supported");
|
||||
ensure_target(#'v1_0.target'{address = Address,
|
||||
durable = Durable},
|
||||
Vhost, User, PermCache) ->
|
||||
|
|
@ -2549,7 +2545,7 @@ check_exchange(XNameBin, RKey, QNameBin, User, Vhost, PermCache0) ->
|
|||
end,
|
||||
{ok, Exchange, RKey, QNameBin, PermCache};
|
||||
{error, not_found} ->
|
||||
not_found(XName)
|
||||
exit_not_found(XName)
|
||||
end.
|
||||
|
||||
ensure_target_v1({utf8, Address}, Vhost, User, Durable, PermCache0) ->
|
||||
|
|
@ -2908,16 +2904,16 @@ keyfind_unpack_described(Key, KvList) ->
|
|||
end.
|
||||
|
||||
validate_attach(#'v1_0.attach'{target = #'v1_0.coordinator'{}}) ->
|
||||
not_implemented("Transactions not supported");
|
||||
exit_not_implemented("Transactions not supported");
|
||||
validate_attach(#'v1_0.attach'{unsettled = {map, [_|_]}}) ->
|
||||
not_implemented("Link recovery not supported");
|
||||
exit_not_implemented("Link recovery not supported");
|
||||
validate_attach(#'v1_0.attach'{incomplete_unsettled = true}) ->
|
||||
not_implemented("Link recovery not supported");
|
||||
exit_not_implemented("Link recovery not supported");
|
||||
validate_attach(
|
||||
#'v1_0.attach'{snd_settle_mode = SndSettleMode,
|
||||
rcv_settle_mode = ?V_1_0_RECEIVER_SETTLE_MODE_SECOND})
|
||||
when SndSettleMode =/= ?V_1_0_SENDER_SETTLE_MODE_SETTLED ->
|
||||
not_implemented("rcv-settle-mode second not supported");
|
||||
exit_not_implemented("rcv-settle-mode second not supported");
|
||||
validate_attach(#'v1_0.attach'{}) ->
|
||||
ok.
|
||||
|
||||
|
|
@ -2951,7 +2947,7 @@ validate_multi_transfer_settled(Other, First)
|
|||
%% "If the message is being sent settled by the sender,
|
||||
%% the value of this field [rcv-settle-mode] is ignored." [2.7.5]
|
||||
validate_transfer_rcv_settle_mode(?V_1_0_RECEIVER_SETTLE_MODE_SECOND, _Settled = false) ->
|
||||
not_implemented("rcv-settle-mode second not supported");
|
||||
exit_not_implemented("rcv-settle-mode second not supported");
|
||||
validate_transfer_rcv_settle_mode(_, _) ->
|
||||
ok.
|
||||
|
||||
|
|
@ -3025,7 +3021,7 @@ exit_if_absent(ResourceName = #resource{kind = Kind}) ->
|
|||
end,
|
||||
case Mod:exists(ResourceName) of
|
||||
true -> ok;
|
||||
false -> not_found(ResourceName)
|
||||
false -> exit_not_found(ResourceName)
|
||||
end.
|
||||
|
||||
generate_queue_name() ->
|
||||
|
|
@ -3072,10 +3068,10 @@ outcomes(#'v1_0.source'{outcomes = {array, symbol, Syms} = Outcomes}) ->
|
|||
[] ->
|
||||
Outcomes;
|
||||
Unsupported ->
|
||||
not_implemented("Outcomes not supported: ~tp", [Unsupported])
|
||||
exit_not_implemented("Outcomes not supported: ~tp", [Unsupported])
|
||||
end;
|
||||
outcomes(#'v1_0.source'{outcomes = Unsupported}) ->
|
||||
not_implemented("Outcomes not supported: ~tp", [Unsupported]);
|
||||
exit_not_implemented("Outcomes not supported: ~tp", [Unsupported]);
|
||||
outcomes(_) ->
|
||||
{array, symbol, ?OUTCOMES}.
|
||||
|
||||
|
|
@ -3330,30 +3326,37 @@ check_paired({map, Properties}) ->
|
|||
true ->
|
||||
ok;
|
||||
false ->
|
||||
property_paired_not_set()
|
||||
exit_property_paired_not_set()
|
||||
end;
|
||||
check_paired(_) ->
|
||||
property_paired_not_set().
|
||||
exit_property_paired_not_set().
|
||||
|
||||
-spec property_paired_not_set() -> no_return().
|
||||
property_paired_not_set() ->
|
||||
-spec exit_property_paired_not_set() -> no_return().
|
||||
exit_property_paired_not_set() ->
|
||||
protocol_error(?V_1_0_AMQP_ERROR_INVALID_FIELD,
|
||||
"Link property 'paired' is not set to boolean value 'true'", []).
|
||||
|
||||
-spec not_implemented(io:format()) -> no_return().
|
||||
not_implemented(Format) ->
|
||||
not_implemented(Format, []).
|
||||
-spec exit_not_implemented(io:format()) -> no_return().
|
||||
exit_not_implemented(Format) ->
|
||||
exit_not_implemented(Format, []).
|
||||
|
||||
-spec not_implemented(io:format(), [term()]) -> no_return().
|
||||
not_implemented(Format, Args) ->
|
||||
-spec exit_not_implemented(io:format(), [term()]) -> no_return().
|
||||
exit_not_implemented(Format, Args) ->
|
||||
protocol_error(?V_1_0_AMQP_ERROR_NOT_IMPLEMENTED, Format, Args).
|
||||
|
||||
-spec not_found(rabbit_types:r(exchange | queue)) -> no_return().
|
||||
not_found(Resource) ->
|
||||
-spec exit_not_found(rabbit_types:r(exchange | queue)) -> no_return().
|
||||
exit_not_found(Resource) ->
|
||||
protocol_error(?V_1_0_AMQP_ERROR_NOT_FOUND,
|
||||
"no ~ts",
|
||||
[rabbit_misc:rs(Resource)]).
|
||||
|
||||
-spec error_not_found(rabbit_types:r(exchange | queue)) -> #'v1_0.error'{}.
|
||||
error_not_found(Resource) ->
|
||||
Description = unicode:characters_to_binary("no " ++ rabbit_misc:rs(Resource)),
|
||||
#'v1_0.error'{
|
||||
condition = ?V_1_0_AMQP_ERROR_NOT_FOUND,
|
||||
description = {utf8, Description}}.
|
||||
|
||||
address_v1_permitted() ->
|
||||
rabbit_deprecated_features:is_permitted(amqp_address_v1).
|
||||
|
||||
|
|
|
|||
|
|
@ -391,16 +391,19 @@ target_per_message_unset_to_address(Config) ->
|
|||
ok = wait_for_credit(Sender),
|
||||
|
||||
%% Send message with 'to' unset.
|
||||
ok = amqp10_client:send_msg(Sender, amqp10_msg:new(<<0>>, <<0>>)),
|
||||
receive
|
||||
{amqp10_event,
|
||||
{session, Session,
|
||||
{ended,
|
||||
#'v1_0.error'{
|
||||
condition = ?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
|
||||
description = {utf8, <<"anonymous terminus requires 'to' address to be set">>}}}}} -> ok
|
||||
after 5000 -> ct:fail({missing_event, ?LINE})
|
||||
DTag = <<1>>,
|
||||
ok = amqp10_client:send_msg(Sender, amqp10_msg:new(DTag, <<0>>)),
|
||||
ok = wait_for_settled(released, DTag),
|
||||
receive {amqp10_event,
|
||||
{link, Sender,
|
||||
{detached,
|
||||
#'v1_0.error'{
|
||||
condition = ?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
|
||||
description = {utf8, <<"anonymous terminus requires 'to' address to be set">>}}}}} -> ok
|
||||
after 5000 -> ct:fail("server did not close our outgoing link")
|
||||
end,
|
||||
|
||||
ok = amqp10_client:end_session(Session),
|
||||
ok = amqp10_client:close_connection(Connection).
|
||||
|
||||
bad_v2_addresses() ->
|
||||
|
|
@ -436,17 +439,20 @@ target_per_message_bad_to_address0(Address, Config) ->
|
|||
{ok, Sender} = amqp10_client:attach_sender_link(Session, <<"sender">>, null),
|
||||
ok = wait_for_credit(Sender),
|
||||
|
||||
Msg = amqp10_msg:set_properties(#{to => Address}, amqp10_msg:new(<<0>>, <<0>>)),
|
||||
DTag = <<255>>,
|
||||
Msg = amqp10_msg:set_properties(#{to => Address}, amqp10_msg:new(DTag, <<0>>)),
|
||||
ok = amqp10_client:send_msg(Sender, Msg),
|
||||
receive
|
||||
{amqp10_event,
|
||||
{session, Session,
|
||||
{ended,
|
||||
#'v1_0.error'{
|
||||
condition = ?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
|
||||
description = {utf8, <<"bad 'to' address", _Rest/binary>>}}}}} -> ok
|
||||
after 5000 -> ct:fail({missing_event, ?LINE, Address})
|
||||
ok = wait_for_settled(released, DTag),
|
||||
receive {amqp10_event,
|
||||
{link, Sender,
|
||||
{detached,
|
||||
#'v1_0.error'{
|
||||
condition = ?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
|
||||
description = {utf8, <<"bad 'to' address", _Rest/binary>>}}}}} -> ok
|
||||
after 5000 -> ct:fail("server did not close our outgoing link")
|
||||
end,
|
||||
|
||||
ok = amqp10_client:end_session(Session),
|
||||
ok = amqp10_client:close_connection(Connection).
|
||||
|
||||
target_per_message_exchange_absent(Config) ->
|
||||
|
|
|
|||
Loading…
Reference in New Issue