Skip to content

Commit b9f387b

Browse files
Merge pull request #11412 from rabbitmq/link-error
Prefer link error over session error
2 parents 5e4a432 + 895bf3e commit b9f387b

File tree

2 files changed

+64
-55
lines changed

2 files changed

+64
-55
lines changed

deps/rabbit/src/rabbit_amqp_session.erl

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2305,12 +2305,8 @@ incoming_link_transfer(
23052305
"delivery_tag=~p, delivery_id=~p, reason=~p",
23062306
[DeliveryTag, DeliveryId, Reason])
23072307
end;
2308-
{error, not_found, XName} ->
2308+
{error, #'v1_0.error'{} = Err} ->
23092309
Disposition = released(DeliveryId),
2310-
Description = unicode:characters_to_binary("no " ++ rabbit_misc:rs(XName)),
2311-
Err = #'v1_0.error'{
2312-
condition = ?V_1_0_AMQP_ERROR_NOT_FOUND,
2313-
description = {utf8, Description}},
23142310
Detach = detach(HandleInt, Link0, Err),
23152311
{error, [Disposition, Detach]}
23162312
end.
@@ -2322,7 +2318,7 @@ lookup_target(#resource{} = XName, LinkRKey, Mc, _, _, PermCache) ->
23222318
{ok, X} ->
23232319
lookup_routing_key(X, LinkRKey, Mc, PermCache);
23242320
{error, not_found} ->
2325-
{error, not_found, XName}
2321+
{error, error_not_found(XName)}
23262322
end;
23272323
lookup_target(to, to, Mc, Vhost, User, PermCache0) ->
23282324
case mc:property(to, Mc) of
@@ -2336,19 +2332,19 @@ lookup_target(to, to, Mc, Vhost, User, PermCache0) ->
23362332
check_internal_exchange(X),
23372333
lookup_routing_key(X, RKey, Mc, PermCache);
23382334
{error, not_found} ->
2339-
{error, not_found, XName}
2335+
{error, error_not_found(XName)}
23402336
end;
23412337
{error, bad_address} ->
2342-
protocol_error(
2343-
?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
2344-
"bad 'to' address string: ~ts",
2345-
[String])
2338+
{error,
2339+
#'v1_0.error'{
2340+
condition = ?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
2341+
description = {utf8, <<"bad 'to' address string: ", String/binary>>}}}
23462342
end;
23472343
undefined ->
2348-
protocol_error(
2349-
?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
2350-
"anonymous terminus requires 'to' address to be set",
2351-
[])
2344+
{error,
2345+
#'v1_0.error'{
2346+
condition = ?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
2347+
description = {utf8, <<"anonymous terminus requires 'to' address to be set">>}}}
23522348
end.
23532349

23542350
lookup_routing_key(X = #exchange{name = #resource{name = XNameBin}},
@@ -2430,7 +2426,7 @@ maybe_grant_mgmt_link_credit(Credit, _, _) ->
24302426
{ok, rabbit_amqqueue:name(), permission_cache(), topic_permission_cache()} |
24312427
{error, term()}.
24322428
ensure_source(#'v1_0.source'{dynamic = true}, _, _, _, _) ->
2433-
not_implemented("Dynamic sources not supported");
2429+
exit_not_implemented("Dynamic sources not supported");
24342430
ensure_source(#'v1_0.source'{address = Address,
24352431
durable = Durable},
24362432
Vhost, User, PermCache, TopicPermCache) ->
@@ -2504,7 +2500,7 @@ ensure_source_v2(Address, _, _, _) ->
25042500
permission_cache()} |
25052501
{error, term()}.
25062502
ensure_target(#'v1_0.target'{dynamic = true}, _, _, _) ->
2507-
not_implemented("Dynamic targets not supported");
2503+
exit_not_implemented("Dynamic targets not supported");
25082504
ensure_target(#'v1_0.target'{address = Address,
25092505
durable = Durable},
25102506
Vhost, User, PermCache) ->
@@ -2549,7 +2545,7 @@ check_exchange(XNameBin, RKey, QNameBin, User, Vhost, PermCache0) ->
25492545
end,
25502546
{ok, Exchange, RKey, QNameBin, PermCache};
25512547
{error, not_found} ->
2552-
not_found(XName)
2548+
exit_not_found(XName)
25532549
end.
25542550

25552551
ensure_target_v1({utf8, Address}, Vhost, User, Durable, PermCache0) ->
@@ -2908,16 +2904,16 @@ keyfind_unpack_described(Key, KvList) ->
29082904
end.
29092905

29102906
validate_attach(#'v1_0.attach'{target = #'v1_0.coordinator'{}}) ->
2911-
not_implemented("Transactions not supported");
2907+
exit_not_implemented("Transactions not supported");
29122908
validate_attach(#'v1_0.attach'{unsettled = {map, [_|_]}}) ->
2913-
not_implemented("Link recovery not supported");
2909+
exit_not_implemented("Link recovery not supported");
29142910
validate_attach(#'v1_0.attach'{incomplete_unsettled = true}) ->
2915-
not_implemented("Link recovery not supported");
2911+
exit_not_implemented("Link recovery not supported");
29162912
validate_attach(
29172913
#'v1_0.attach'{snd_settle_mode = SndSettleMode,
29182914
rcv_settle_mode = ?V_1_0_RECEIVER_SETTLE_MODE_SECOND})
29192915
when SndSettleMode =/= ?V_1_0_SENDER_SETTLE_MODE_SETTLED ->
2920-
not_implemented("rcv-settle-mode second not supported");
2916+
exit_not_implemented("rcv-settle-mode second not supported");
29212917
validate_attach(#'v1_0.attach'{}) ->
29222918
ok.
29232919

@@ -2951,7 +2947,7 @@ validate_multi_transfer_settled(Other, First)
29512947
%% "If the message is being sent settled by the sender,
29522948
%% the value of this field [rcv-settle-mode] is ignored." [2.7.5]
29532949
validate_transfer_rcv_settle_mode(?V_1_0_RECEIVER_SETTLE_MODE_SECOND, _Settled = false) ->
2954-
not_implemented("rcv-settle-mode second not supported");
2950+
exit_not_implemented("rcv-settle-mode second not supported");
29552951
validate_transfer_rcv_settle_mode(_, _) ->
29562952
ok.
29572953

@@ -3025,7 +3021,7 @@ exit_if_absent(ResourceName = #resource{kind = Kind}) ->
30253021
end,
30263022
case Mod:exists(ResourceName) of
30273023
true -> ok;
3028-
false -> not_found(ResourceName)
3024+
false -> exit_not_found(ResourceName)
30293025
end.
30303026

30313027
generate_queue_name() ->
@@ -3072,10 +3068,10 @@ outcomes(#'v1_0.source'{outcomes = {array, symbol, Syms} = Outcomes}) ->
30723068
[] ->
30733069
Outcomes;
30743070
Unsupported ->
3075-
not_implemented("Outcomes not supported: ~tp", [Unsupported])
3071+
exit_not_implemented("Outcomes not supported: ~tp", [Unsupported])
30763072
end;
30773073
outcomes(#'v1_0.source'{outcomes = Unsupported}) ->
3078-
not_implemented("Outcomes not supported: ~tp", [Unsupported]);
3074+
exit_not_implemented("Outcomes not supported: ~tp", [Unsupported]);
30793075
outcomes(_) ->
30803076
{array, symbol, ?OUTCOMES}.
30813077

@@ -3330,30 +3326,37 @@ check_paired({map, Properties}) ->
33303326
true ->
33313327
ok;
33323328
false ->
3333-
property_paired_not_set()
3329+
exit_property_paired_not_set()
33343330
end;
33353331
check_paired(_) ->
3336-
property_paired_not_set().
3332+
exit_property_paired_not_set().
33373333

3338-
-spec property_paired_not_set() -> no_return().
3339-
property_paired_not_set() ->
3334+
-spec exit_property_paired_not_set() -> no_return().
3335+
exit_property_paired_not_set() ->
33403336
protocol_error(?V_1_0_AMQP_ERROR_INVALID_FIELD,
33413337
"Link property 'paired' is not set to boolean value 'true'", []).
33423338

3343-
-spec not_implemented(io:format()) -> no_return().
3344-
not_implemented(Format) ->
3345-
not_implemented(Format, []).
3339+
-spec exit_not_implemented(io:format()) -> no_return().
3340+
exit_not_implemented(Format) ->
3341+
exit_not_implemented(Format, []).
33463342

3347-
-spec not_implemented(io:format(), [term()]) -> no_return().
3348-
not_implemented(Format, Args) ->
3343+
-spec exit_not_implemented(io:format(), [term()]) -> no_return().
3344+
exit_not_implemented(Format, Args) ->
33493345
protocol_error(?V_1_0_AMQP_ERROR_NOT_IMPLEMENTED, Format, Args).
33503346

3351-
-spec not_found(rabbit_types:r(exchange | queue)) -> no_return().
3352-
not_found(Resource) ->
3347+
-spec exit_not_found(rabbit_types:r(exchange | queue)) -> no_return().
3348+
exit_not_found(Resource) ->
33533349
protocol_error(?V_1_0_AMQP_ERROR_NOT_FOUND,
33543350
"no ~ts",
33553351
[rabbit_misc:rs(Resource)]).
33563352

3353+
-spec error_not_found(rabbit_types:r(exchange | queue)) -> #'v1_0.error'{}.
3354+
error_not_found(Resource) ->
3355+
Description = unicode:characters_to_binary("no " ++ rabbit_misc:rs(Resource)),
3356+
#'v1_0.error'{
3357+
condition = ?V_1_0_AMQP_ERROR_NOT_FOUND,
3358+
description = {utf8, Description}}.
3359+
33573360
address_v1_permitted() ->
33583361
rabbit_deprecated_features:is_permitted(amqp_address_v1).
33593362

deps/rabbit/test/amqp_address_SUITE.erl

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -391,16 +391,19 @@ target_per_message_unset_to_address(Config) ->
391391
ok = wait_for_credit(Sender),
392392

393393
%% Send message with 'to' unset.
394-
ok = amqp10_client:send_msg(Sender, amqp10_msg:new(<<0>>, <<0>>)),
395-
receive
396-
{amqp10_event,
397-
{session, Session,
398-
{ended,
399-
#'v1_0.error'{
400-
condition = ?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
401-
description = {utf8, <<"anonymous terminus requires 'to' address to be set">>}}}}} -> ok
402-
after 5000 -> ct:fail({missing_event, ?LINE})
394+
DTag = <<1>>,
395+
ok = amqp10_client:send_msg(Sender, amqp10_msg:new(DTag, <<0>>)),
396+
ok = wait_for_settled(released, DTag),
397+
receive {amqp10_event,
398+
{link, Sender,
399+
{detached,
400+
#'v1_0.error'{
401+
condition = ?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
402+
description = {utf8, <<"anonymous terminus requires 'to' address to be set">>}}}}} -> ok
403+
after 5000 -> ct:fail("server did not close our outgoing link")
403404
end,
405+
406+
ok = amqp10_client:end_session(Session),
404407
ok = amqp10_client:close_connection(Connection).
405408

406409
bad_v2_addresses() ->
@@ -436,17 +439,20 @@ target_per_message_bad_to_address0(Address, Config) ->
436439
{ok, Sender} = amqp10_client:attach_sender_link(Session, <<"sender">>, null),
437440
ok = wait_for_credit(Sender),
438441

439-
Msg = amqp10_msg:set_properties(#{to => Address}, amqp10_msg:new(<<0>>, <<0>>)),
442+
DTag = <<255>>,
443+
Msg = amqp10_msg:set_properties(#{to => Address}, amqp10_msg:new(DTag, <<0>>)),
440444
ok = amqp10_client:send_msg(Sender, Msg),
441-
receive
442-
{amqp10_event,
443-
{session, Session,
444-
{ended,
445-
#'v1_0.error'{
446-
condition = ?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
447-
description = {utf8, <<"bad 'to' address", _Rest/binary>>}}}}} -> ok
448-
after 5000 -> ct:fail({missing_event, ?LINE, Address})
445+
ok = wait_for_settled(released, DTag),
446+
receive {amqp10_event,
447+
{link, Sender,
448+
{detached,
449+
#'v1_0.error'{
450+
condition = ?V_1_0_AMQP_ERROR_PRECONDITION_FAILED,
451+
description = {utf8, <<"bad 'to' address", _Rest/binary>>}}}}} -> ok
452+
after 5000 -> ct:fail("server did not close our outgoing link")
449453
end,
454+
455+
ok = amqp10_client:end_session(Session),
450456
ok = amqp10_client:close_connection(Connection).
451457

452458
target_per_message_exchange_absent(Config) ->

0 commit comments

Comments
 (0)