具有指定类型的函数中的透析器类型错误

Type errors in dialyzer in function with specified type

我在 dialyzer 分析以下函数时收到错误消息。

-spec do_request(Method, Type, Url, Expect, Headers, Body, Client) -> Response::client_response() 
when 
    Method  :: method(),
    Type    :: content_type(),
    Url     :: url(),
    Expect  :: status_codes(),
    Headers :: headers(),
    Body    :: body(),
    Client  :: #client{}.

do_request(Method, Type, Url, Expect, Headers, Body, Client) -> 
    Client2 = check_expired(Client),
    Headers2 = add_auth_header(Headers, Client2),
    %% error occurs on this line
    Response = restc:request(Method, Type, binary_to_list(Url), Expect, Headers2, Body),
    %%
    {Response, Client2}.

错误是:

The call restc:request(Method::any(),Type::any(),
[byte()],Expect::any(),Headers2::[{binary(),binary()},...],
Body::any()) breaks the contract (Method::method(), Type::content_type(),  
Url::url(), Expect::status_codes(), Headers::headers(), 
Body::body()) -> Response::response()

restc:request 具有以下类型规范:

-spec request(Method::method(), Type::content_type(), Url::url(),
Expect::status_codes(), Headers::headers(), Body::body()) -> Response::response().

调用使用的类型有:

-type method()       :: head | get | put | post | trace | options | delete.
-type url()          :: binary().
-type headers()      :: [header()].
-type header()       :: {binary(), binary()}.
-type status_codes() :: [status_code()].
-type status_code()  :: integer().
-type reason()       :: term().
-type content_type() :: json | xml | percent.
-type property()     :: atom() | tuple().
-type proplist()     :: [property()].
-type body()         :: proplist().
-type response()     :: {ok, Status::status_code(), Headers::headers(), Body::body()} |
                        {error, Status::status_code(), Headers::headers(), Body::body()} |
                        {error, Reason::reason()}.
-type client_response()       :: {response(), #client{}}.
-type token_type()     :: bearer | unsupported.

为什么 dialyzer 说我的调用正在传递 any() 类型的变量,而我已经指定了要传递的变量的类型?我查看了调用链以验证类型规范是否一致(并且与其他模块一致)。

问题是 url() 被指定为 binary() 但你在其中传递了 [byte()] (字符串)。您需要将 url() 的类型规范更改为 iodata() 之类的内容,或者通过先将其转换为二进制来限制您的输入。