summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2013-03-15 14:00:15 +0000
committerSimon MacMullen <simon@rabbitmq.com>2013-03-15 14:00:15 +0000
commit74e8e188e249319d66fe816f448ca2c19a50330d (patch)
tree1dd7edfdd48c3f64808d70e35b376cc95995d640
parentfaf5177eebe306d79d91a8e1d6b59cd72daa81a8 (diff)
downloadrabbitmq-server-74e8e188e249319d66fe816f448ca2c19a50330d.tar.gz
Push protocol errors closer to the edge.
-rw-r--r--src/rabbit_binding.erl4
-rw-r--r--src/rabbit_channel.erl2
-rw-r--r--src/rabbit_exchange.erl9
-rw-r--r--src/rabbit_exchange_type.erl6
-rw-r--r--src/rabbit_exchange_type_headers.erl17
5 files changed, 18 insertions, 20 deletions
diff --git a/src/rabbit_binding.erl b/src/rabbit_binding.erl
index 6bc17482..f1197a84 100644
--- a/src/rabbit_binding.erl
+++ b/src/rabbit_binding.erl
@@ -39,7 +39,9 @@
{'resources_missing',
[{'not_found', (rabbit_types:binding_source() |
rabbit_types:binding_destination())} |
- {'absent', rabbit_types:amqqueue()}]})).
+ {'absent', rabbit_types:amqqueue()}]} |
+ {'binding_invalid', string(), [any()]})).
+
-type(bind_ok_or_error() :: 'ok' | bind_errors() |
rabbit_types:error('binding_not_found')).
-type(bind_res() :: bind_ok_or_error() | rabbit_misc:thunk(bind_ok_or_error())).
diff --git a/src/rabbit_channel.erl b/src/rabbit_channel.erl
index 0510afa9..792a06c9 100644
--- a/src/rabbit_channel.erl
+++ b/src/rabbit_channel.erl
@@ -1194,6 +1194,8 @@ binding_action(Fun, ExchangeNameBin, DestinationType, DestinationNameBin,
not_found, "no binding ~s between ~s and ~s",
[RoutingKey, rabbit_misc:rs(ExchangeName),
rabbit_misc:rs(DestinationName)]);
+ {error, {binding_invalid, Fmt, Args}} ->
+ rabbit_misc:protocol_error(precondition_failed, Fmt, Args);
{error, #amqp_error{} = Error} ->
rabbit_misc:protocol_error(Error);
ok -> return_ok(State, NoWait, ReturnMethod)
diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl
index 18ec83c1..2de7f8a4 100644
--- a/src/rabbit_exchange.erl
+++ b/src/rabbit_exchange.erl
@@ -85,7 +85,7 @@
rabbit_types:error('in_use')).
-spec(validate_binding/2 ::
(rabbit_types:exchange(), rabbit_types:binding())
- -> rabbit_types:ok_or_error(rabbit_types:amqp_error())).
+ -> rabbit_types:ok_or_error({'binding_invalid', string(), [any()]})).
-spec(maybe_auto_delete/1::
(rabbit_types:exchange())
-> 'not_deleted' | {'deleted', rabbit_binding:deletions()}).
@@ -404,12 +404,7 @@ delete(XName, IfUnused) ->
validate_binding(X = #exchange{type = XType}, Binding) ->
Module = type_to_module(XType),
- try
- Module:validate_binding(X, Binding)
- catch
- exit:Error ->
- {error, Error}
- end.
+ Module:validate_binding(X, Binding).
maybe_auto_delete(#exchange{auto_delete = false}) ->
not_deleted;
diff --git a/src/rabbit_exchange_type.erl b/src/rabbit_exchange_type.erl
index 01001fa2..acb7d772 100644
--- a/src/rabbit_exchange_type.erl
+++ b/src/rabbit_exchange_type.erl
@@ -37,9 +37,9 @@
%% called BEFORE declaration, to check args etc; may exit with #amqp_error{}
-callback validate(rabbit_types:exchange()) -> 'ok'.
-%% called BEFORE declaration, to check args etc; may exit with #amqp_error{}
--callback validate_binding(
- rabbit_types:exchange(), rabbit_types:binding()) -> 'ok'.
+%% called BEFORE declaration, to check args etc
+-callback validate_binding(rabbit_types:exchange(), rabbit_types:binding()) ->
+ rabbit_types:ok_or_error({'binding_invalid', string(), [any()]}).
%% called after declaration and recovery
-callback create(tx(), rabbit_types:exchange()) -> 'ok'.
diff --git a/src/rabbit_exchange_type_headers.erl b/src/rabbit_exchange_type_headers.erl
index a78dce73..c03dc5d2 100644
--- a/src/rabbit_exchange_type_headers.erl
+++ b/src/rabbit_exchange_type_headers.erl
@@ -55,17 +55,16 @@ validate_binding(_X, #binding{args = Args}) ->
case rabbit_misc:table_lookup(Args, <<"x-match">>) of
{longstr, <<"all">>} -> ok;
{longstr, <<"any">>} -> ok;
- {longstr, Other} -> rabbit_misc:protocol_error(
- precondition_failed,
+ {longstr, Other} -> {error,
+ {binding_invalid,
"Invalid x-match field value ~p; "
- "expected all or any", [Other]);
- {Type, Other} -> rabbit_misc:protocol_error(
- precondition_failed,
+ "expected all or any", [Other]}};
+ {Type, Other} -> {error,
+ {binding_invalid,
"Invalid x-match field type ~p (value ~p); "
- "expected longstr", [Type, Other]);
- undefined -> rabbit_misc:protocol_error(
- precondition_failed,
- "x-match field missing", [])
+ "expected longstr", [Type, Other]}};
+ undefined -> {error,
+ {binding_invalid, "x-match field missing", []}}
end.
parse_x_match(<<"all">>) -> all;