diff --git a/include/message_pb.hrl b/include/message_pb.hrl index 9f7a2d3..cc8acf3 100644 --- a/include/message_pb.hrl +++ b/include/message_pb.hrl @@ -75,10 +75,25 @@ }). -endif. +-ifndef('RPCREPLY.RPCRESULT_PB_H'). +-define('RPCREPLY.RPCRESULT_PB_H', true). +-record('RpcReply.RpcResult', + {data = <<>> :: iodata() | undefined % = 1, optional + }). +-endif. + +-ifndef('RPCREPLY.RPCERROR_PB_H'). +-define('RPCREPLY.RPCERROR_PB_H', true). +-record('RpcReply.RpcError', + {code = 0 :: integer() | undefined, % = 1, optional, 32 bits + message = <<>> :: unicode:chardata() | undefined % = 2, optional + }). +-endif. + -ifndef('RPCREPLY_PB_H'). -define('RPCREPLY_PB_H', true). -record('RpcReply', - {body :: {result, iodata()} | {error, iodata()} | undefined % oneof + {reply :: {result, message_pb:'RpcReply.RpcResult'()} | {error, message_pb:'RpcReply.RpcError'()} | undefined % oneof }). -endif. diff --git a/proto/message.proto b/proto/message.proto index 8d37c08..6c56585 100644 --- a/proto/message.proto +++ b/proto/message.proto @@ -58,9 +58,18 @@ message RpcRequest { } message RpcReply { - oneof body { - bytes result = 1; - bytes error = 2; + message RpcResult { + bytes data = 1; + } + + message RpcError { + int32 code = 1; + string message = 2; + } + + oneof reply { + RpcResult result = 1; + RpcError error = 2; } } diff --git a/src/host/iot_host.erl b/src/host/iot_host.erl index 3211d8c..b4cde78 100644 --- a/src/host/iot_host.erl +++ b/src/host/iot_host.erl @@ -129,17 +129,18 @@ remove_container(Pid, ContainerName) when is_pid(Pid), is_binary(ContainerName) Params = jiffy:encode(#{<<"container_name">> => ContainerName}, [force_utf8]), gen_statem:call(Pid, {jsonrpc_call, self(), {<<"remove_container">>, Params}}). --spec await_reply(Pid :: pid(), Ref :: reference(), Timeout :: integer()) -> {ok, Result :: binary()} | {error, Reason :: binary()}. +-spec await_reply(Pid :: pid(), Ref :: reference(), Timeout :: integer()) -> + {ok, Result :: binary()} | {error, Code :: integer(), Reason :: binary()}. await_reply(Pid, Ref, Timeout) when is_pid(Pid), is_reference(Ref), is_integer(Timeout) -> receive - {rpc_reply, Ref, #'RpcReply'{body = {result, ResultBin}}} -> + {rpc_reply, Ref, #'RpcReply'{reply = {result, #'RpcReply.RpcResult'{data = ResultBin}}}} -> {ok, iolist_to_binary(ResultBin)}; - {rpc_reply, Ref, #'RpcReply'{body = {error, ErrorBin}}} -> - {error, iolist_to_binary(ErrorBin)} + {rpc_reply, Ref, #'RpcReply'{reply = {error, #'RpcReply.RpcError'{code = Code, message = Message}}}} -> + {error, Code, unicode:characters_to_binary(Message)} after Timeout -> ok = gen_statem:call(Pid, {cancel_jsonrpc_call, Ref}), flush_reply(Ref), - {error, <<"timeout">>} + {error, -1, <<"timeout">>} end. -spec pub(Pid :: pid(), Topic :: binary(), Qos :: integer(), Content :: binary()) -> ok | {error, Reason :: any()}. diff --git a/src/protobuf/message_pb.erl b/src/protobuf/message_pb.erl index d4a57f8..6d6dd87 100644 --- a/src/protobuf/message_pb.erl +++ b/src/protobuf/message_pb.erl @@ -70,15 +70,19 @@ -type 'RpcRequest'() :: #'RpcRequest'{}. +-type 'RpcReply.RpcResult'() :: #'RpcReply.RpcResult'{}. + +-type 'RpcReply.RpcError'() :: #'RpcReply.RpcError'{}. + -type 'RpcReply'() :: #'RpcReply'{}. -type 'Data'() :: #'Data'{}. -type 'TaskEventStream'() :: #'TaskEventStream'{}. --export_type(['RequestFrame'/0, 'ResponseFrame'/0, 'CastFrame'/0, 'AuthRequest'/0, 'AuthReply'/0, 'Pub'/0, 'Command'/0, 'RpcRequest'/0, 'RpcReply'/0, 'Data'/0, 'TaskEventStream'/0]). --type '$msg_name'() :: 'RequestFrame' | 'ResponseFrame' | 'CastFrame' | 'AuthRequest' | 'AuthReply' | 'Pub' | 'Command' | 'RpcRequest' | 'RpcReply' | 'Data' | 'TaskEventStream'. --type '$msg'() :: 'RequestFrame'() | 'ResponseFrame'() | 'CastFrame'() | 'AuthRequest'() | 'AuthReply'() | 'Pub'() | 'Command'() | 'RpcRequest'() | 'RpcReply'() | 'Data'() | 'TaskEventStream'(). +-export_type(['RequestFrame'/0, 'ResponseFrame'/0, 'CastFrame'/0, 'AuthRequest'/0, 'AuthReply'/0, 'Pub'/0, 'Command'/0, 'RpcRequest'/0, 'RpcReply.RpcResult'/0, 'RpcReply.RpcError'/0, 'RpcReply'/0, 'Data'/0, 'TaskEventStream'/0]). +-type '$msg_name'() :: 'RequestFrame' | 'ResponseFrame' | 'CastFrame' | 'AuthRequest' | 'AuthReply' | 'Pub' | 'Command' | 'RpcRequest' | 'RpcReply.RpcResult' | 'RpcReply.RpcError' | 'RpcReply' | 'Data' | 'TaskEventStream'. +-type '$msg'() :: 'RequestFrame'() | 'ResponseFrame'() | 'CastFrame'() | 'AuthRequest'() | 'AuthReply'() | 'Pub'() | 'Command'() | 'RpcRequest'() | 'RpcReply.RpcResult'() | 'RpcReply.RpcError'() | 'RpcReply'() | 'Data'() | 'TaskEventStream'(). -export_type(['$msg_name'/0, '$msg'/0]). -if(?OTP_RELEASE >= 24). @@ -113,6 +117,8 @@ encode_msg(Msg, MsgName, Opts) -> 'Pub' -> encode_msg_Pub(id(Msg, TrUserData), TrUserData); 'Command' -> encode_msg_Command(id(Msg, TrUserData), TrUserData); 'RpcRequest' -> encode_msg_RpcRequest(id(Msg, TrUserData), TrUserData); + 'RpcReply.RpcResult' -> 'encode_msg_RpcReply.RpcResult'(id(Msg, TrUserData), TrUserData); + 'RpcReply.RpcError' -> 'encode_msg_RpcReply.RpcError'(id(Msg, TrUserData), TrUserData); 'RpcReply' -> encode_msg_RpcReply(id(Msg, TrUserData), TrUserData); 'Data' -> encode_msg_Data(id(Msg, TrUserData), TrUserData); 'TaskEventStream' -> encode_msg_TaskEventStream(id(Msg, TrUserData), TrUserData) @@ -336,15 +342,54 @@ encode_msg_RpcRequest(#'RpcRequest'{method = F1, params = F2}, Bin, TrUserData) end end. +'encode_msg_RpcReply.RpcResult'(Msg, TrUserData) -> 'encode_msg_RpcReply.RpcResult'(Msg, <<>>, TrUserData). + + +'encode_msg_RpcReply.RpcResult'(#'RpcReply.RpcResult'{data = F1}, Bin, TrUserData) -> + if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + case iolist_size(TrF1) of + 0 -> Bin; + _ -> e_type_bytes(TrF1, <>, TrUserData) + end + end + end. + +'encode_msg_RpcReply.RpcError'(Msg, TrUserData) -> 'encode_msg_RpcReply.RpcError'(Msg, <<>>, TrUserData). + + +'encode_msg_RpcReply.RpcError'(#'RpcReply.RpcError'{code = F1, message = F2}, Bin, TrUserData) -> + B1 = if F1 == undefined -> Bin; + true -> + begin + TrF1 = id(F1, TrUserData), + if TrF1 =:= 0 -> Bin; + true -> e_type_int32(TrF1, <>, TrUserData) + end + end + end, + if F2 == undefined -> B1; + true -> + begin + TrF2 = id(F2, TrUserData), + case is_empty_string(TrF2) of + true -> B1; + false -> e_type_string(TrF2, <>, TrUserData) + end + end + end. + encode_msg_RpcReply(Msg, TrUserData) -> encode_msg_RpcReply(Msg, <<>>, TrUserData). -encode_msg_RpcReply(#'RpcReply'{body = F1}, Bin, TrUserData) -> +encode_msg_RpcReply(#'RpcReply'{reply = F1}, Bin, TrUserData) -> if F1 =:= undefined -> Bin; true -> case id(F1, TrUserData) of - {result, TF1} -> begin TrTF1 = id(TF1, TrUserData), e_type_bytes(TrTF1, <>, TrUserData) end; - {error, TF1} -> begin TrTF1 = id(TF1, TrUserData), e_type_bytes(TrTF1, <>, TrUserData) end + {result, TF1} -> begin TrTF1 = id(TF1, TrUserData), e_mfield_RpcReply_result(TrTF1, <>, TrUserData) end; + {error, TF1} -> begin TrTF1 = id(TF1, TrUserData), e_mfield_RpcReply_error(TrTF1, <>, TrUserData) end end end. @@ -447,6 +492,16 @@ e_mfield_CastFrame_event_stream(Msg, Bin, TrUserData) -> Bin2 = e_varint(byte_size(SubBin), Bin), <>. +e_mfield_RpcReply_result(Msg, Bin, TrUserData) -> + SubBin = 'encode_msg_RpcReply.RpcResult'(Msg, <<>>, TrUserData), + Bin2 = e_varint(byte_size(SubBin), Bin), + <>. + +e_mfield_RpcReply_error(Msg, Bin, TrUserData) -> + SubBin = 'encode_msg_RpcReply.RpcError'(Msg, <<>>, TrUserData), + Bin2 = e_varint(byte_size(SubBin), Bin), + <>. + -compile({nowarn_unused_function,e_type_sint/3}). e_type_sint(Value, Bin, _TrUserData) when Value >= 0 -> e_varint(Value * 2, Bin); e_type_sint(Value, Bin, _TrUserData) -> e_varint(Value * -2 - 1, Bin). @@ -541,6 +596,22 @@ e_varint(N, Bin) -> Bin2 = <>, e_varint(N bsr 7, Bin2). +is_empty_string("") -> true; +is_empty_string(<<>>) -> true; +is_empty_string(L) when is_list(L) -> not string_has_chars(L); +is_empty_string(B) when is_binary(B) -> false. + +string_has_chars([C | _]) when is_integer(C) -> true; +string_has_chars([H | T]) -> + case string_has_chars(H) of + true -> true; + false -> string_has_chars(T) + end; +string_has_chars(B) when is_binary(B), byte_size(B) =/= 0 -> true; +string_has_chars(C) when is_integer(C) -> true; +string_has_chars(<<>>) -> false; +string_has_chars([]) -> false. + decode_msg(Bin, MsgName) when is_binary(Bin) -> decode_msg(Bin, MsgName, []). @@ -577,6 +648,8 @@ decode_msg_2_doit('AuthReply', Bin, TrUserData) -> id(decode_msg_AuthReply(Bin, decode_msg_2_doit('Pub', Bin, TrUserData) -> id(decode_msg_Pub(Bin, TrUserData), TrUserData); decode_msg_2_doit('Command', Bin, TrUserData) -> id(decode_msg_Command(Bin, TrUserData), TrUserData); decode_msg_2_doit('RpcRequest', Bin, TrUserData) -> id(decode_msg_RpcRequest(Bin, TrUserData), TrUserData); +decode_msg_2_doit('RpcReply.RpcResult', Bin, TrUserData) -> id('decode_msg_RpcReply.RpcResult'(Bin, TrUserData), TrUserData); +decode_msg_2_doit('RpcReply.RpcError', Bin, TrUserData) -> id('decode_msg_RpcReply.RpcError'(Bin, TrUserData), TrUserData); decode_msg_2_doit('RpcReply', Bin, TrUserData) -> id(decode_msg_RpcReply(Bin, TrUserData), TrUserData); decode_msg_2_doit('Data', Bin, TrUserData) -> id(decode_msg_Data(Bin, TrUserData), TrUserData); decode_msg_2_doit('TaskEventStream', Bin, TrUserData) -> id(decode_msg_TaskEventStream(Bin, TrUserData), TrUserData). @@ -1123,11 +1196,106 @@ skip_32_RpcRequest(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> skip_64_RpcRequest(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_RpcRequest(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). +'decode_msg_RpcReply.RpcResult'(Bin, TrUserData) -> 'dfp_read_field_def_RpcReply.RpcResult'(Bin, 0, 0, 0, id(<<>>, TrUserData), TrUserData). + +'dfp_read_field_def_RpcReply.RpcResult'(<<10, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> 'd_field_RpcReply.RpcResult_data'(Rest, Z1, Z2, F, F@_1, TrUserData); +'dfp_read_field_def_RpcReply.RpcResult'(<<>>, 0, 0, _, F@_1, _) -> #'RpcReply.RpcResult'{data = F@_1}; +'dfp_read_field_def_RpcReply.RpcResult'(Other, Z1, Z2, F, F@_1, TrUserData) -> 'dg_read_field_def_RpcReply.RpcResult'(Other, Z1, Z2, F, F@_1, TrUserData). + +'dg_read_field_def_RpcReply.RpcResult'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 32 - 7 -> 'dg_read_field_def_RpcReply.RpcResult'(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +'dg_read_field_def_RpcReply.RpcResult'(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 10 -> 'd_field_RpcReply.RpcResult_data'(Rest, 0, 0, 0, F@_1, TrUserData); + _ -> + case Key band 7 of + 0 -> 'skip_varint_RpcReply.RpcResult'(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 1 -> 'skip_64_RpcReply.RpcResult'(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 2 -> 'skip_length_delimited_RpcReply.RpcResult'(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 3 -> 'skip_group_RpcReply.RpcResult'(Rest, 0, 0, Key bsr 3, F@_1, TrUserData); + 5 -> 'skip_32_RpcReply.RpcResult'(Rest, 0, 0, Key bsr 3, F@_1, TrUserData) + end + end; +'dg_read_field_def_RpcReply.RpcResult'(<<>>, 0, 0, _, F@_1, _) -> #'RpcReply.RpcResult'{data = F@_1}. + +'d_field_RpcReply.RpcResult_data'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> 'd_field_RpcReply.RpcResult_data'(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +'d_field_RpcReply.RpcResult_data'(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + 'dfp_read_field_def_RpcReply.RpcResult'(RestF, 0, 0, F, NewFValue, TrUserData). + +'skip_varint_RpcReply.RpcResult'(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> 'skip_varint_RpcReply.RpcResult'(Rest, Z1, Z2, F, F@_1, TrUserData); +'skip_varint_RpcReply.RpcResult'(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> 'dfp_read_field_def_RpcReply.RpcResult'(Rest, Z1, Z2, F, F@_1, TrUserData). + +'skip_length_delimited_RpcReply.RpcResult'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> 'skip_length_delimited_RpcReply.RpcResult'(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); +'skip_length_delimited_RpcReply.RpcResult'(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + 'dfp_read_field_def_RpcReply.RpcResult'(Rest2, 0, 0, F, F@_1, TrUserData). + +'skip_group_RpcReply.RpcResult'(Bin, _, Z2, FNum, F@_1, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + 'dfp_read_field_def_RpcReply.RpcResult'(Rest, 0, Z2, FNum, F@_1, TrUserData). + +'skip_32_RpcReply.RpcResult'(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> 'dfp_read_field_def_RpcReply.RpcResult'(Rest, Z1, Z2, F, F@_1, TrUserData). + +'skip_64_RpcReply.RpcResult'(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> 'dfp_read_field_def_RpcReply.RpcResult'(Rest, Z1, Z2, F, F@_1, TrUserData). + +'decode_msg_RpcReply.RpcError'(Bin, TrUserData) -> 'dfp_read_field_def_RpcReply.RpcError'(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), TrUserData). + +'dfp_read_field_def_RpcReply.RpcError'(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'd_field_RpcReply.RpcError_code'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +'dfp_read_field_def_RpcReply.RpcError'(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'd_field_RpcReply.RpcError_message'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +'dfp_read_field_def_RpcReply.RpcError'(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'RpcReply.RpcError'{code = F@_1, message = F@_2}; +'dfp_read_field_def_RpcReply.RpcError'(Other, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'dg_read_field_def_RpcReply.RpcError'(Other, Z1, Z2, F, F@_1, F@_2, TrUserData). + +'dg_read_field_def_RpcReply.RpcError'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 32 - 7 -> 'dg_read_field_def_RpcReply.RpcError'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +'dg_read_field_def_RpcReply.RpcError'(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, TrUserData) -> + Key = X bsl N + Acc, + case Key of + 8 -> 'd_field_RpcReply.RpcError_code'(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + 18 -> 'd_field_RpcReply.RpcError_message'(Rest, 0, 0, 0, F@_1, F@_2, TrUserData); + _ -> + case Key band 7 of + 0 -> 'skip_varint_RpcReply.RpcError'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 1 -> 'skip_64_RpcReply.RpcError'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 2 -> 'skip_length_delimited_RpcReply.RpcError'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 3 -> 'skip_group_RpcReply.RpcError'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData); + 5 -> 'skip_32_RpcReply.RpcError'(Rest, 0, 0, Key bsr 3, F@_1, F@_2, TrUserData) + end + end; +'dg_read_field_def_RpcReply.RpcError'(<<>>, 0, 0, _, F@_1, F@_2, _) -> #'RpcReply.RpcError'{code = F@_1, message = F@_2}. + +'d_field_RpcReply.RpcError_code'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> 'd_field_RpcReply.RpcError_code'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +'d_field_RpcReply.RpcError_code'(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, TrUserData) -> + {NewFValue, RestF} = {begin <> = <<(X bsl N + Acc):32/unsigned-native>>, id(Res, TrUserData) end, Rest}, + 'dfp_read_field_def_RpcReply.RpcError'(RestF, 0, 0, F, NewFValue, F@_2, TrUserData). + +'d_field_RpcReply.RpcError_message'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> 'd_field_RpcReply.RpcError_message'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +'d_field_RpcReply.RpcError_message'(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, + 'dfp_read_field_def_RpcReply.RpcError'(RestF, 0, 0, F, F@_1, NewFValue, TrUserData). + +'skip_varint_RpcReply.RpcError'(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'skip_varint_RpcReply.RpcError'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData); +'skip_varint_RpcReply.RpcError'(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'dfp_read_field_def_RpcReply.RpcError'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +'skip_length_delimited_RpcReply.RpcError'(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) when N < 57 -> 'skip_length_delimited_RpcReply.RpcError'(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, TrUserData); +'skip_length_delimited_RpcReply.RpcError'(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, TrUserData) -> + Length = X bsl N + Acc, + <<_:Length/binary, Rest2/binary>> = Rest, + 'dfp_read_field_def_RpcReply.RpcError'(Rest2, 0, 0, F, F@_1, F@_2, TrUserData). + +'skip_group_RpcReply.RpcError'(Bin, _, Z2, FNum, F@_1, F@_2, TrUserData) -> + {_, Rest} = read_group(Bin, FNum), + 'dfp_read_field_def_RpcReply.RpcError'(Rest, 0, Z2, FNum, F@_1, F@_2, TrUserData). + +'skip_32_RpcReply.RpcError'(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'dfp_read_field_def_RpcReply.RpcError'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + +'skip_64_RpcReply.RpcError'(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> 'dfp_read_field_def_RpcReply.RpcError'(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData). + decode_msg_RpcReply(Bin, TrUserData) -> dfp_read_field_def_RpcReply(Bin, 0, 0, 0, id(undefined, TrUserData), TrUserData). dfp_read_field_def_RpcReply(<<10, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> d_field_RpcReply_result(Rest, Z1, Z2, F, F@_1, TrUserData); dfp_read_field_def_RpcReply(<<18, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> d_field_RpcReply_error(Rest, Z1, Z2, F, F@_1, TrUserData); -dfp_read_field_def_RpcReply(<<>>, 0, 0, _, F@_1, _) -> #'RpcReply'{body = F@_1}; +dfp_read_field_def_RpcReply(<<>>, 0, 0, _, F@_1, _) -> #'RpcReply'{reply = F@_1}; dfp_read_field_def_RpcReply(Other, Z1, Z2, F, F@_1, TrUserData) -> dg_read_field_def_RpcReply(Other, Z1, Z2, F, F@_1, TrUserData). dg_read_field_def_RpcReply(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 32 - 7 -> dg_read_field_def_RpcReply(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); @@ -1145,17 +1313,35 @@ dg_read_field_def_RpcReply(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, TrUserDat 5 -> skip_32_RpcReply(Rest, 0, 0, Key bsr 3, F@_1, TrUserData) end end; -dg_read_field_def_RpcReply(<<>>, 0, 0, _, F@_1, _) -> #'RpcReply'{body = F@_1}. +dg_read_field_def_RpcReply(<<>>, 0, 0, _, F@_1, _) -> #'RpcReply'{reply = F@_1}. d_field_RpcReply_result(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> d_field_RpcReply_result(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); -d_field_RpcReply_result(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_RpcReply(RestF, 0, 0, F, id({result, NewFValue}, TrUserData), TrUserData). +d_field_RpcReply_result(<<0:1, X:7, Rest/binary>>, N, Acc, F, Prev, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id('decode_msg_RpcReply.RpcResult'(Bs, TrUserData), TrUserData), Rest2} end, + dfp_read_field_def_RpcReply(RestF, + 0, + 0, + F, + case Prev of + undefined -> id({result, NewFValue}, TrUserData); + {result, MVPrev} -> id({result, 'merge_msg_RpcReply.RpcResult'(MVPrev, NewFValue, TrUserData)}, TrUserData); + _ -> id({result, NewFValue}, TrUserData) + end, + TrUserData). d_field_RpcReply_error(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, TrUserData) when N < 57 -> d_field_RpcReply_error(Rest, N + 7, X bsl N + Acc, F, F@_1, TrUserData); -d_field_RpcReply_error(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, TrUserData) -> - {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, - dfp_read_field_def_RpcReply(RestF, 0, 0, F, id({error, NewFValue}, TrUserData), TrUserData). +d_field_RpcReply_error(<<0:1, X:7, Rest/binary>>, N, Acc, F, Prev, TrUserData) -> + {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, {id('decode_msg_RpcReply.RpcError'(Bs, TrUserData), TrUserData), Rest2} end, + dfp_read_field_def_RpcReply(RestF, + 0, + 0, + F, + case Prev of + undefined -> id({error, NewFValue}, TrUserData); + {error, MVPrev} -> id({error, 'merge_msg_RpcReply.RpcError'(MVPrev, NewFValue, TrUserData)}, TrUserData); + _ -> id({error, NewFValue}, TrUserData) + end, + TrUserData). skip_varint_RpcReply(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> skip_varint_RpcReply(Rest, Z1, Z2, F, F@_1, TrUserData); skip_varint_RpcReply(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, TrUserData) -> dfp_read_field_def_RpcReply(Rest, Z1, Z2, F, F@_1, TrUserData). @@ -1357,6 +1543,8 @@ merge_msgs(Prev, New, MsgName, Opts) -> 'Pub' -> merge_msg_Pub(Prev, New, TrUserData); 'Command' -> merge_msg_Command(Prev, New, TrUserData); 'RpcRequest' -> merge_msg_RpcRequest(Prev, New, TrUserData); + 'RpcReply.RpcResult' -> 'merge_msg_RpcReply.RpcResult'(Prev, New, TrUserData); + 'RpcReply.RpcError' -> 'merge_msg_RpcReply.RpcError'(Prev, New, TrUserData); 'RpcReply' -> merge_msg_RpcReply(Prev, New, TrUserData); 'Data' -> merge_msg_Data(Prev, New, TrUserData); 'TaskEventStream' -> merge_msg_TaskEventStream(Prev, New, TrUserData) @@ -1473,11 +1661,32 @@ merge_msg_RpcRequest(#'RpcRequest'{method = PFmethod, params = PFparams}, #'RpcR true -> NFparams end}. +-compile({nowarn_unused_function,'merge_msg_RpcReply.RpcResult'/3}). +'merge_msg_RpcReply.RpcResult'(#'RpcReply.RpcResult'{data = PFdata}, #'RpcReply.RpcResult'{data = NFdata}, _) -> + #'RpcReply.RpcResult'{data = + if NFdata =:= undefined -> PFdata; + true -> NFdata + end}. + +-compile({nowarn_unused_function,'merge_msg_RpcReply.RpcError'/3}). +'merge_msg_RpcReply.RpcError'(#'RpcReply.RpcError'{code = PFcode, message = PFmessage}, #'RpcReply.RpcError'{code = NFcode, message = NFmessage}, _) -> + #'RpcReply.RpcError'{code = + if NFcode =:= undefined -> PFcode; + true -> NFcode + end, + message = + if NFmessage =:= undefined -> PFmessage; + true -> NFmessage + end}. + -compile({nowarn_unused_function,merge_msg_RpcReply/3}). -merge_msg_RpcReply(#'RpcReply'{body = PFbody}, #'RpcReply'{body = NFbody}, _) -> - #'RpcReply'{body = - if NFbody =:= undefined -> PFbody; - true -> NFbody +merge_msg_RpcReply(#'RpcReply'{reply = PFreply}, #'RpcReply'{reply = NFreply}, TrUserData) -> + #'RpcReply'{reply = + case {PFreply, NFreply} of + {{result, OPFreply}, {result, ONFreply}} -> {result, 'merge_msg_RpcReply.RpcResult'(OPFreply, ONFreply, TrUserData)}; + {{error, OPFreply}, {error, ONFreply}} -> {error, 'merge_msg_RpcReply.RpcError'(OPFreply, ONFreply, TrUserData)}; + {_, undefined} -> PFreply; + _ -> NFreply end}. -compile({nowarn_unused_function,merge_msg_Data/3}). @@ -1525,6 +1734,8 @@ verify_msg(Msg, MsgName, Opts) -> 'Pub' -> v_msg_Pub(Msg, [MsgName], TrUserData); 'Command' -> v_msg_Command(Msg, [MsgName], TrUserData); 'RpcRequest' -> v_msg_RpcRequest(Msg, [MsgName], TrUserData); + 'RpcReply.RpcResult' -> 'v_msg_RpcReply.RpcResult'(Msg, [MsgName], TrUserData); + 'RpcReply.RpcError' -> 'v_msg_RpcReply.RpcError'(Msg, [MsgName], TrUserData); 'RpcReply' -> v_msg_RpcReply(Msg, [MsgName], TrUserData); 'Data' -> v_msg_Data(Msg, [MsgName], TrUserData); 'TaskEventStream' -> v_msg_TaskEventStream(Msg, [MsgName], TrUserData); @@ -1668,18 +1879,47 @@ v_msg_RpcRequest(#'RpcRequest'{method = F1, params = F2}, Path, TrUserData) -> ok; v_msg_RpcRequest(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'RpcRequest'}, X, Path). +-compile({nowarn_unused_function,'v_submsg_RpcReply.RpcResult'/3}). +-dialyzer({nowarn_function,'v_submsg_RpcReply.RpcResult'/3}). +'v_submsg_RpcReply.RpcResult'(Msg, Path, TrUserData) -> 'v_msg_RpcReply.RpcResult'(Msg, Path, TrUserData). + +-compile({nowarn_unused_function,'v_msg_RpcReply.RpcResult'/3}). +-dialyzer({nowarn_function,'v_msg_RpcReply.RpcResult'/3}). +'v_msg_RpcReply.RpcResult'(#'RpcReply.RpcResult'{data = F1}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_bytes(F1, [data | Path], TrUserData) + end, + ok; +'v_msg_RpcReply.RpcResult'(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'RpcReply.RpcResult'}, X, Path). + +-compile({nowarn_unused_function,'v_submsg_RpcReply.RpcError'/3}). +-dialyzer({nowarn_function,'v_submsg_RpcReply.RpcError'/3}). +'v_submsg_RpcReply.RpcError'(Msg, Path, TrUserData) -> 'v_msg_RpcReply.RpcError'(Msg, Path, TrUserData). + +-compile({nowarn_unused_function,'v_msg_RpcReply.RpcError'/3}). +-dialyzer({nowarn_function,'v_msg_RpcReply.RpcError'/3}). +'v_msg_RpcReply.RpcError'(#'RpcReply.RpcError'{code = F1, message = F2}, Path, TrUserData) -> + if F1 == undefined -> ok; + true -> v_type_int32(F1, [code | Path], TrUserData) + end, + if F2 == undefined -> ok; + true -> v_type_string(F2, [message | Path], TrUserData) + end, + ok; +'v_msg_RpcReply.RpcError'(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'RpcReply.RpcError'}, X, Path). + -compile({nowarn_unused_function,v_submsg_RpcReply/3}). -dialyzer({nowarn_function,v_submsg_RpcReply/3}). v_submsg_RpcReply(Msg, Path, TrUserData) -> v_msg_RpcReply(Msg, Path, TrUserData). -compile({nowarn_unused_function,v_msg_RpcReply/3}). -dialyzer({nowarn_function,v_msg_RpcReply/3}). -v_msg_RpcReply(#'RpcReply'{body = F1}, Path, TrUserData) -> +v_msg_RpcReply(#'RpcReply'{reply = F1}, Path, TrUserData) -> case F1 of undefined -> ok; - {result, OF1} -> v_type_bytes(OF1, [result, body | Path], TrUserData); - {error, OF1} -> v_type_bytes(OF1, [error, body | Path], TrUserData); - _ -> mk_type_error(invalid_oneof, F1, [body | Path]) + {result, OF1} -> 'v_submsg_RpcReply.RpcResult'(OF1, [result, reply | Path], TrUserData); + {error, OF1} -> 'v_submsg_RpcReply.RpcError'(OF1, [error, reply | Path], TrUserData); + _ -> mk_type_error(invalid_oneof, F1, [reply | Path]) end, ok; v_msg_RpcReply(X, Path, _TrUserData) -> mk_type_error({expected_msg, 'RpcReply'}, X, Path). @@ -1731,6 +1971,17 @@ v_type_uint32(N, _Path, _TrUserData) when is_integer(N), 0 =< N, N =< 4294967295 v_type_uint32(N, Path, _TrUserData) when is_integer(N) -> mk_type_error({value_out_of_range, uint32, unsigned, 32}, N, Path); v_type_uint32(X, Path, _TrUserData) -> mk_type_error({bad_integer, uint32, unsigned, 32}, X, Path). +-compile({nowarn_unused_function,v_type_string/3}). +-dialyzer({nowarn_function,v_type_string/3}). +v_type_string(S, Path, _TrUserData) when is_list(S); is_binary(S) -> + try unicode:characters_to_binary(S) of + B when is_binary(B) -> ok; + {error, _, _} -> mk_type_error(bad_unicode_string, S, Path) + catch + error:badarg -> mk_type_error(bad_unicode_string, S, Path) + end; +v_type_string(X, Path, _TrUserData) -> mk_type_error(bad_unicode_string, X, Path). + -compile({nowarn_unused_function,v_type_bytes/3}). -dialyzer({nowarn_function,v_type_bytes/3}). v_type_bytes(B, _Path, _TrUserData) when is_binary(B) -> ok; @@ -1804,8 +2055,11 @@ get_msg_defs() -> #field{name = content, fnum = 3, rnum = 4, type = bytes, occurrence = optional, opts = []}]}, {{msg, 'Command'}, [#field{name = command_type, fnum = 1, rnum = 2, type = int32, occurrence = optional, opts = []}, #field{name = command, fnum = 2, rnum = 3, type = bytes, occurrence = optional, opts = []}]}, {{msg, 'RpcRequest'}, [#field{name = method, fnum = 1, rnum = 2, type = bytes, occurrence = optional, opts = []}, #field{name = params, fnum = 2, rnum = 3, type = bytes, occurrence = optional, opts = []}]}, + {{msg, 'RpcReply.RpcResult'}, [#field{name = data, fnum = 1, rnum = 2, type = bytes, occurrence = optional, opts = []}]}, + {{msg, 'RpcReply.RpcError'}, [#field{name = code, fnum = 1, rnum = 2, type = int32, occurrence = optional, opts = []}, #field{name = message, fnum = 2, rnum = 3, type = string, occurrence = optional, opts = []}]}, {{msg, 'RpcReply'}, - [#gpb_oneof{name = body, rnum = 2, fields = [#field{name = result, fnum = 1, rnum = 2, type = bytes, occurrence = optional, opts = []}, #field{name = error, fnum = 2, rnum = 2, type = bytes, occurrence = optional, opts = []}], opts = []}]}, + [#gpb_oneof{name = reply, rnum = 2, + fields = [#field{name = result, fnum = 1, rnum = 2, type = {msg, 'RpcReply.RpcResult'}, occurrence = optional, opts = []}, #field{name = error, fnum = 2, rnum = 2, type = {msg, 'RpcReply.RpcError'}, occurrence = optional, opts = []}], opts = []}]}, {{msg, 'Data'}, [#field{name = route_key, fnum = 1, rnum = 2, type = bytes, occurrence = optional, opts = []}, #field{name = metric, fnum = 2, rnum = 3, type = bytes, occurrence = optional, opts = []}]}, {{msg, 'TaskEventStream'}, [#field{name = task_id, fnum = 1, rnum = 2, type = int32, occurrence = optional, opts = []}, @@ -1813,13 +2067,13 @@ get_msg_defs() -> #field{name = stream, fnum = 3, rnum = 4, type = bytes, occurrence = optional, opts = []}]}]. -get_msg_names() -> ['RequestFrame', 'ResponseFrame', 'CastFrame', 'AuthRequest', 'AuthReply', 'Pub', 'Command', 'RpcRequest', 'RpcReply', 'Data', 'TaskEventStream']. +get_msg_names() -> ['RequestFrame', 'ResponseFrame', 'CastFrame', 'AuthRequest', 'AuthReply', 'Pub', 'Command', 'RpcRequest', 'RpcReply.RpcResult', 'RpcReply.RpcError', 'RpcReply', 'Data', 'TaskEventStream']. get_group_names() -> []. -get_msg_or_group_names() -> ['RequestFrame', 'ResponseFrame', 'CastFrame', 'AuthRequest', 'AuthReply', 'Pub', 'Command', 'RpcRequest', 'RpcReply', 'Data', 'TaskEventStream']. +get_msg_or_group_names() -> ['RequestFrame', 'ResponseFrame', 'CastFrame', 'AuthRequest', 'AuthReply', 'Pub', 'Command', 'RpcRequest', 'RpcReply.RpcResult', 'RpcReply.RpcError', 'RpcReply', 'Data', 'TaskEventStream']. get_enum_names() -> []. @@ -1865,8 +2119,11 @@ find_msg_def('Pub') -> #field{name = content, fnum = 3, rnum = 4, type = bytes, occurrence = optional, opts = []}]; find_msg_def('Command') -> [#field{name = command_type, fnum = 1, rnum = 2, type = int32, occurrence = optional, opts = []}, #field{name = command, fnum = 2, rnum = 3, type = bytes, occurrence = optional, opts = []}]; find_msg_def('RpcRequest') -> [#field{name = method, fnum = 1, rnum = 2, type = bytes, occurrence = optional, opts = []}, #field{name = params, fnum = 2, rnum = 3, type = bytes, occurrence = optional, opts = []}]; +find_msg_def('RpcReply.RpcResult') -> [#field{name = data, fnum = 1, rnum = 2, type = bytes, occurrence = optional, opts = []}]; +find_msg_def('RpcReply.RpcError') -> [#field{name = code, fnum = 1, rnum = 2, type = int32, occurrence = optional, opts = []}, #field{name = message, fnum = 2, rnum = 3, type = string, occurrence = optional, opts = []}]; find_msg_def('RpcReply') -> - [#gpb_oneof{name = body, rnum = 2, fields = [#field{name = result, fnum = 1, rnum = 2, type = bytes, occurrence = optional, opts = []}, #field{name = error, fnum = 2, rnum = 2, type = bytes, occurrence = optional, opts = []}], opts = []}]; + [#gpb_oneof{name = reply, rnum = 2, + fields = [#field{name = result, fnum = 1, rnum = 2, type = {msg, 'RpcReply.RpcResult'}, occurrence = optional, opts = []}, #field{name = error, fnum = 2, rnum = 2, type = {msg, 'RpcReply.RpcError'}, occurrence = optional, opts = []}], opts = []}]; find_msg_def('Data') -> [#field{name = route_key, fnum = 1, rnum = 2, type = bytes, occurrence = optional, opts = []}, #field{name = metric, fnum = 2, rnum = 3, type = bytes, occurrence = optional, opts = []}]; find_msg_def('TaskEventStream') -> [#field{name = task_id, fnum = 1, rnum = 2, type = int32, occurrence = optional, opts = []}, @@ -1938,6 +2195,8 @@ fqbin_to_msg_name(<<"AuthReply">>) -> 'AuthReply'; fqbin_to_msg_name(<<"Pub">>) -> 'Pub'; fqbin_to_msg_name(<<"Command">>) -> 'Command'; fqbin_to_msg_name(<<"RpcRequest">>) -> 'RpcRequest'; +fqbin_to_msg_name(<<"RpcReply.RpcResult">>) -> 'RpcReply.RpcResult'; +fqbin_to_msg_name(<<"RpcReply.RpcError">>) -> 'RpcReply.RpcError'; fqbin_to_msg_name(<<"RpcReply">>) -> 'RpcReply'; fqbin_to_msg_name(<<"Data">>) -> 'Data'; fqbin_to_msg_name(<<"TaskEventStream">>) -> 'TaskEventStream'; @@ -1952,6 +2211,8 @@ msg_name_to_fqbin('AuthReply') -> <<"AuthReply">>; msg_name_to_fqbin('Pub') -> <<"Pub">>; msg_name_to_fqbin('Command') -> <<"Command">>; msg_name_to_fqbin('RpcRequest') -> <<"RpcRequest">>; +msg_name_to_fqbin('RpcReply.RpcResult') -> <<"RpcReply.RpcResult">>; +msg_name_to_fqbin('RpcReply.RpcError') -> <<"RpcReply.RpcError">>; msg_name_to_fqbin('RpcReply') -> <<"RpcReply">>; msg_name_to_fqbin('Data') -> <<"Data">>; msg_name_to_fqbin('TaskEventStream') -> <<"TaskEventStream">>; @@ -1993,7 +2254,7 @@ get_all_source_basenames() -> ["message.proto"]. get_all_proto_names() -> ["message"]. -get_msg_containment("message") -> ['AuthReply', 'AuthRequest', 'CastFrame', 'Command', 'Data', 'Pub', 'RequestFrame', 'ResponseFrame', 'RpcReply', 'RpcRequest', 'TaskEventStream']; +get_msg_containment("message") -> ['AuthReply', 'AuthRequest', 'CastFrame', 'Command', 'Data', 'Pub', 'RequestFrame', 'ResponseFrame', 'RpcReply', 'RpcReply.RpcError', 'RpcReply.RpcResult', 'RpcRequest', 'TaskEventStream']; get_msg_containment(P) -> error({gpb_error, {badproto, P}}). @@ -2014,8 +2275,10 @@ get_enum_containment(P) -> error({gpb_error, {badproto, P}}). get_proto_by_msg_name_as_fqbin(<<"Data">>) -> "message"; +get_proto_by_msg_name_as_fqbin(<<"RpcReply.RpcError">>) -> "message"; get_proto_by_msg_name_as_fqbin(<<"Pub">>) -> "message"; get_proto_by_msg_name_as_fqbin(<<"RpcRequest">>) -> "message"; +get_proto_by_msg_name_as_fqbin(<<"RpcReply.RpcResult">>) -> "message"; get_proto_by_msg_name_as_fqbin(<<"Command">>) -> "message"; get_proto_by_msg_name_as_fqbin(<<"AuthRequest">>) -> "message"; get_proto_by_msg_name_as_fqbin(<<"ResponseFrame">>) -> "message"; diff --git a/src/transport/http/container_handler.erl b/src/transport/http/container_handler.erl index 0c133e1..68c1099 100644 --- a/src/transport/http/container_handler.erl +++ b/src/transport/http/container_handler.erl @@ -26,8 +26,8 @@ handle_request("GET", "/container/get_all", #{<<"uuid">> := UUID}, _) when is_bi case iot_host:await_reply(Pid, Ref, ?REQ_TIMEOUT) of {ok, Result} -> {ok, 200, rpc_success_response(Result)}; - {error, Reason} -> - {ok, 200, rpc_error_response(-1, Reason)} + {error, Code, Reason} -> + rpc_error_http_response(Code, Reason) end; {error, Reason} when is_binary(Reason) -> {ok, 200, iot_util:json_error(-1, Reason)} @@ -51,8 +51,8 @@ handle_request("POST", "/container/push_config", _, case iot_host:await_reply(Pid, Ref, Timeout) of {ok, Result} -> {ok, 200, rpc_success_response(Result)}; - {error, Reason} -> - {ok, 200, rpc_error_response(-1, Reason)} + {error, Code, Reason} -> + rpc_error_http_response(Code, Reason) end; {error, Reason} when is_binary(Reason) -> {ok, 200, iot_util:json_error(-1, Reason)} @@ -78,8 +78,8 @@ handle_request("POST", "/container/deploy", _, #{<<"uuid">> := UUID, <<"task_id" case iot_host:await_reply(Pid, Ref, ?REQ_TIMEOUT) of {ok, Result} -> {ok, 200, rpc_success_response(Result)}; - {error, Reason} -> - {ok, 200, rpc_error_response(400, Reason)} + {error, Code, Reason} -> + rpc_error_http_response(Code, Reason) end; {error, Reason} when is_binary(Reason) -> {ok, 200, iot_util:json_error(400, Reason)} @@ -101,8 +101,8 @@ handle_request("POST", "/container/start", _, #{<<"uuid">> := UUID, <<"container case iot_host:await_reply(Pid, Ref, ?REQ_TIMEOUT) of {ok, Result} -> {ok, 200, rpc_success_response(Result)}; - {error, Reason} -> - {ok, 200, rpc_error_response(400, Reason)} + {error, Code, Reason} -> + rpc_error_http_response(Code, Reason) end; {error, Reason} when is_binary(Reason) -> {ok, 200, iot_util:json_error(400, Reason)} @@ -120,8 +120,8 @@ handle_request("POST", "/container/stop", _, #{<<"uuid">> := UUID, <<"container_ case iot_host:await_reply(Pid, Ref, ?REQ_TIMEOUT) of {ok, Result} -> {ok, 200, rpc_success_response(Result)}; - {error, Reason} -> - {ok, 200, rpc_error_response(400, Reason)} + {error, Code, Reason} -> + rpc_error_http_response(Code, Reason) end; {error, Reason} when is_binary(Reason) -> {ok, 200, iot_util:json_error(400, Reason)} @@ -138,8 +138,8 @@ handle_request("POST", "/container/kill", _, #{<<"uuid">> := UUID, <<"container_ case iot_host:await_reply(Pid, Ref, ?REQ_TIMEOUT) of {ok, Result} -> {ok, 200, rpc_success_response(Result)}; - {error, Reason} -> - {ok, 200, rpc_error_response(400, Reason)} + {error, Code, Reason} -> + rpc_error_http_response(Code, Reason) end; {error, Reason} when is_binary(Reason) -> {ok, 200, iot_util:json_error(400, Reason)} @@ -157,8 +157,8 @@ handle_request("POST", "/container/remove", _, #{<<"uuid">> := UUID, <<"containe case iot_host:await_reply(Pid, Ref, ?REQ_TIMEOUT) of {ok, Result} -> {ok, 200, rpc_success_response(Result)}; - {error, Reason} -> - {ok, 200, rpc_error_response(400, Reason)} + {error, Code, Reason} -> + rpc_error_http_response(Code, Reason) end; {error, Reason} when is_binary(Reason) -> {ok, 200, iot_util:json_error(400, Reason)} @@ -330,6 +330,19 @@ rpc_error_response(Code, Reason) when is_integer(Code), is_binary(Reason) -> iot_util:json_error(Code, Reason) end. +-spec rpc_error_http_response(Code :: integer(), Reason :: binary()) -> + {ok, HttpStatus :: integer(), Body :: iolist()}. +rpc_error_http_response(Code, Reason) when is_integer(Code), is_binary(Reason) -> + {ok, rpc_error_status(Code), rpc_error_response(Code, Reason)}. + +-spec rpc_error_status(Code :: integer()) -> integer(). +rpc_error_status(Code) when is_integer(Code), Code >= 400, Code < 600 -> + Code; +rpc_error_status(-1) -> + 504; +rpc_error_status(_) -> + 400. + decode_json_bytes(Data) when is_binary(Data) -> case catch jiffy:decode(Data, [return_maps]) of {'EXIT', _} ->