我用这段代码测试:
get_fee(Transaction,SourceNumber,Amount, Currency) ->
Url = lists:concat(["http://localhost/test.php","?transaction=", Transaction, "&saccount=", SourceNumber,Amount,"¤cy=",Currency]),
inets:start(),
{Flag, Response} = http:request(get, {Url, []}, [], []),
case Flag of
ok ->
{ { _, ReturnCode, _ }, _, Body } = Response,
if ReturnCode =:= 200 ->
{ok,{_,[{_,Code},{_,Permission},{_,Payer},{_,Payee}]}} = json:decode_string(Body),
case Permission of true ->
if Code =:= 200 ->
{ok,{Code, Payer, Payee}};
Code =:= 204 ->
{nok,{Code, not_found}};
true ->
{nok,{Code, parameter_error}}
end;
false ->
{nok,{Code, parameter_error}}
end;
true->
{error, http_error}
end;
error ->
case Response of
nxdomain -> {error, dns_error};
_ -> {error, network_error}
end
end.
Run Code Online (Sandbox Code Playgroud)
http的响应是: {"code":200,"permission":true,"fee_payer":0,"fee_payee":19}
但是现在我喜欢做同样的想法但是在这种情况下http的返回例如是:
{"CIN":"08321224","Name":21}
Run Code Online (Sandbox Code Playgroud)
所以我在这种情况下只有CIN和Name
我试着改变以前的
get_fee(Num) ->
Url = lists:concat(["http://localhost/GTW/Operation.php","?ACCOUNT_NUM=", Num]),
inets:start(),
{Flag, Response} = http:request(get, {Url, []}, [], []),
case Flag of
ok ->
{ { _, ReturnCode, _ }, _, Body } = Response,
%% for debug
io:format("~p~n",[ReturnCode]),
if ReturnCode =:= "08321224" ->
{ok,{_,[{_,CIN},{_,Name}]}} = json:decode_string(Body),
case Name of 21 ->
io:format(CIN),
io:format(Name),
if CIN =:= "08321224"->
{ok,{CIN, Name}};
CIN =:= 204 ->
{nok,{CIN, not_found}};
true ->
{nok,{CIN, parameter_error}}
end;
false ->
{nok,{CIN, parameter_error}}
end;
true->
{error, http_error}
end;
error ->
case Response of
nxdomain -> {error, dns_error};
_ -> {error, network_error}
%% for debug
%%io:format("pass2~n ~p~n",[Response]),
end
end.
Run Code Online (Sandbox Code Playgroud)
但它显示:
test:get_fee("0001").
200
{error,http_error}
Run Code Online (Sandbox Code Playgroud)
所以我会挑选这里的风格,因为如果你遵循Erlang的语义,你会好得多:
get_fee(Num) ->
Url = lists:concat(["http://localhost/GTW/Operation.php","?ACCOUNT_NUM=", Num]),
inets:start(),
Run Code Online (Sandbox Code Playgroud)
这是一个错误的起点inets.它应该在此功能之外启动,因为您只需要执行此操作.
{Flag, Response} = http:request(get, {Url, []}, [], []),
Run Code Online (Sandbox Code Playgroud)
这部分用模式匹配更好地编码.辨别Flag和Response可以通过简单的匹配直接解码.写,
case http:request(get, {Url, []}, [], []) of
{ok, {{_, 200, _}, _, Body}} ->
{ok, R} = json:decode_string(Body),
get_fee_decode_(get_cin(R), get_name(R));
{error, Reason} -> {error, Reason}
end.
Run Code Online (Sandbox Code Playgroud)
我建议不要改变{error, nxdomain},{error, dns_error}因为nxdomain在任何情况下都能完美地编码这个案例.只需将错误元组传递给调用者并让他处理它.
get_fee_decode_("08321224" = CIN, 21 = Name) -> {ok, {CIN, Name}};
get_fee_decode_("204" = CIN, 21) -> {nok, {CIN, not_found}};
get_fee_decode_(CIN, _Name) -> {nok, {CIN, parameter_error}};
Run Code Online (Sandbox Code Playgroud)
引入一个这样的新函数来处理代码库的内部部分.并将匹配提升到顶级.从长远来看,这有助于将代码分离为函数.
请注意,在JSON结构中,"对象"上没有顺序,因此您不能假设结构是
{"code":200,"permission":true,"fee_payer":0,"fee_payee":19}
Run Code Online (Sandbox Code Playgroud)
但根据JSON,解码不必保留这种结构.所以有效的解码可能是:
[{"fee_payee", 19}, {"fee_payer", 0}, {"permission", true}, {"code", 200}]
Run Code Online (Sandbox Code Playgroud)
这将无法与您的代码匹配,您将在以后为自己设置一些令人讨厌的错误.
你想要的东西是:
get_fee_payer(PL) -> proplists:get_value("fee_payer", PL).
Run Code Online (Sandbox Code Playgroud)
另一个与您的编程风格有关的问题是您隐藏了错误信息案例.在Erlang中,您通常可以通过代码处理"快乐路径"并将所有错误处理保留下来,直到您知道代码库中存在哪种错误为止.然后,您可以开始慢慢添加错误处理.如果可以避免,防御性编程不是你应该做的事情.
| 归档时间: |
|
| 查看次数: |
1230 次 |
| 最近记录: |