Просмотр исходного кода

feat(bridge-api): improve error messages for Update Source API

Andrew Mayorov 1 год назад
Родитель
Сommit
08d88ea814

+ 21 - 4
apps/emqx_bridge/src/emqx_bridge_v2_api.erl

@@ -658,21 +658,38 @@ schema("/source_types") ->
 
 %%------------------------------------------------------------------------------
 
-check_api_schema(Request, ReqMeta = #{path := Path = "/actions/:id", method := put}) ->
-    Spec = maps:get(put, schema(Path)),
+check_api_schema(Request, ReqMeta = #{path := "/actions/:id", method := put}) ->
     BridgeId = emqx_utils_maps:deep_get([bindings, id], Request),
     try emqx_bridge_resource:parse_bridge_id(BridgeId, #{atom_name => false}) of
+        %% NOTE
+        %% Bridge type is known, refine the API schema to get more specific error messages.
         {BridgeType, _Name} ->
             Schema = emqx_bridge_v2_schema:action_api_schema("put", BridgeType),
-            SpecRefined = Spec#{'requestBody' => Schema},
-            emqx_dashboard_swagger:filter_check_request(Request, ReqMeta#{apispec => SpecRefined})
+            emqx_dashboard_swagger:filter_check_request(Request, refine_api_schema(Schema, ReqMeta))
     catch
         throw:#{reason := Reason} ->
             ?NOT_FOUND(<<"Invalid bridge ID, ", Reason/binary>>)
     end;
+check_api_schema(Request, ReqMeta = #{path := "/sources/:id", method := put}) ->
+    SourceId = emqx_utils_maps:deep_get([bindings, id], Request),
+    try emqx_bridge_resource:parse_bridge_id(SourceId, #{atom_name => false}) of
+        %% NOTE
+        %% Source type is known, refine the API schema to get more specific error messages.
+        {BridgeType, _Name} ->
+            Schema = emqx_bridge_v2_schema:source_api_schema("put", BridgeType),
+            emqx_dashboard_swagger:filter_check_request(Request, refine_api_schema(Schema, ReqMeta))
+    catch
+        throw:#{reason := Reason} ->
+            ?NOT_FOUND(<<"Invalid source ID, ", Reason/binary>>)
+    end;
 check_api_schema(Request, ReqMeta) ->
     emqx_dashboard_swagger:filter_check_request(Request, ReqMeta).
 
+refine_api_schema(Schema, ReqMeta = #{path := Path, method := Method}) ->
+    Spec = maps:get(Method, schema(Path)),
+    SpecRefined = Spec#{'requestBody' => Schema},
+    ReqMeta#{apispec => SpecRefined}.
+
 %%------------------------------------------------------------------------------
 %% Thin Handlers
 %%------------------------------------------------------------------------------

+ 19 - 3
apps/emqx_bridge/src/schema/emqx_bridge_v2_schema.erl

@@ -40,6 +40,7 @@
     sources_get_response/0,
     sources_put_request/0,
     sources_post_request/0,
+    source_api_schema/2,
     sources_examples/1,
     source_values/4
 ]).
@@ -169,6 +170,15 @@ sources_api_schema(Method) ->
     APISchemas = ?MODULE:registered_sources_api_schemas(Method),
     hoconsc:union(bridge_api_union(APISchemas)).
 
+source_api_schema(Method, SourceType) ->
+    APISchemas = ?MODULE:registered_sources_api_schemas(Method),
+    case lists:keyfind(atom_to_binary(SourceType), 1, APISchemas) of
+        {_, SchemaRef} ->
+            hoconsc:mk(SchemaRef);
+        false ->
+            unknown_source_schema(SourceType)
+    end.
+
 registered_sources_api_schemas(Method) ->
     RegisteredSchemas = emqx_action_info:registered_schema_modules_sources(),
     [
@@ -241,13 +251,19 @@ bridge_api_union(Refs) ->
             end
     end.
 
--dialyzer({nowarn_function, [unknown_bridge_schema/1]}).
 unknown_bridge_schema(BridgeV2Type) ->
+    erroneous_value_schema(BridgeV2Type, <<"unknown bridge type">>).
+
+unknown_source_schema(SourceType) ->
+    erroneous_value_schema(SourceType, <<"unknown source type">>).
+
+-dialyzer({nowarn_function, [erroneous_value_schema/2]}).
+erroneous_value_schema(Value, Reason) ->
     hoconsc:mk(typerefl:any(), #{
         validator => fun(_) ->
             throw(#{
-                value => BridgeV2Type,
-                reason => <<"unknown bridge type">>
+                value => Value,
+                reason => Reason
             })
         end
     }).