1

我有一个 Erlang 应用程序,它使用 inets 对外部站点进行大量 http 调用,使用下面的代码

case http:request(get, {Url, []}, [{autoredirect, false}], []) of
{ok, {{_, Code, _}, _, Body}}->
    case Code of
    200 ->
        HandlerFn(Body);
    _ ->
        {error, io:format("~s returned HTTP ~p", [Broker, Code])}
    end;
Response -> %% block to handle unexpected responses from inets
    {error, io:format("~s returned ~p", [Broker, Response])}
end.

有一个明确的块来处理任何奇怪的 inets 可能返回 [Response]。尽管如此,我仍然得到看起来像 inets 错误报告转储到控制台 [下面的示例]。我在这里做错了什么?我是否需要在其他地方配置某种 inets 错误处理程序?

谢谢。

--

=ERROR REPORT==== 24-Apr-2010::06:49:47 ===
** Generic server <0.6618.0> terminating 
** Last message in was {connect_and_send,
                           {request,#Ref<0.0.0.139358>,<0.6613.0>,0,http,
                               {"**********",80},
                               "*****************************",
                               [],get,
                               {http_request_h,undefined,"keep-alive",
                                   undefined,undefined,undefined,undefined,
                                   undefined,undefined,undefined,undefined,
                                   undefined,undefined,undefined,undefined,
                                   undefined,undefined,"news.bbc.co.uk",
                                   undefined,undefined,undefined,undefined,
                                   undefined,undefined,undefined,undefined,
                                   undefined,[],undefined,undefined,undefined,
                                   undefined,"0",undefined,undefined,
                                   undefined,undefined,undefined,undefined,[]},
                               {[],[]},
                               {http_options,"HTTP/1.1",infinity,false,[],
                                   undefined,false,infinity},
                               "************************************",
                               [],none,[],1272088179114,undefined,undefined}}
** When Server state == {state,
                            {request,#Ref<0.0.0.139358>,<0.6613.0>,0,http,
                                {"******************",80},
                                "*****************************",
                                [],get,
                                {http_request_h,undefined,"keep-alive",
                                    undefined,undefined,undefined,undefined,
                                    undefined,undefined,undefined,undefined,
                                    undefined,undefined,undefined,undefined,
                                    undefined,undefined,"news.bbc.co.uk",
                                    undefined,undefined,undefined,undefined,
                                    undefined,undefined,undefined,undefined,
                                    undefined,[],undefined,undefined,
                                    undefined,undefined,"0",undefined,
                                    undefined,undefined,undefined,undefined,
                                    undefined,[]},
                                {[],[]},
                                {http_options,"HTTP/1.1",infinity,false,[],
                                    undefined,false,infinity},
                                "****************************************",
                                [],none,[],1272088179114,undefined,undefined},
                            undefined,undefined,undefined,undefined,undefined,
                            {[],[]},
                            {[],[]},
                            undefined,[],nolimit,nolimit,
                            {options,
                                {undefined,[]},
                                0,2,5,120000,2,disabled,false,inet,default,
                                default,[]},
                            {timers,[],undefined},
                            httpc_manager,undefined}
** Reason for termination == 
** {error,{connect_failed,{#Ref<0.0.0.139358>,{error,nxdomain}}}}

=ERROR REPORT==== 24-Apr-2010::06:49:47 ===
HTTPC-MANAGER<httpc_manager> handler (<0.6618.0>, started) failed to connect and/or send request #Ref<0.0.0.139358>
   Result: {error,{connect_failed,{#Ref<0.0.0.139358>,{error,nxdomain}}}}
4

4 回答 4

1

对于您发出的每个 http 请求,都会在“内部”生成一个单独的 httpc_handler 进程。此过程首先尝试打开一个到所需域的套接字。在这种情况下,域不存在,因此打开套接字失败。结果,生成的进程决定停止。

由于处理程序进程是根据 gen_server 原则编写的,因此您的错误处理程序将刷新垂死进程的最后状态。您对此无能为力或应该做的事情。

于 2010-04-24T08:02:45.930 回答
0

我猜想http会创建一个新进程,该进程会随着nxdomain而死。此崩溃 sasl 会在 shell 中拾取并打印。

于 2010-04-24T11:49:36.657 回答
0

假设您的应用程序遵循 OTP 的格式,那么处理 inets 进程的主管应该可配置为重新启动该进程。对于 erlang 应用程序来说,崩溃进程是“正常的”,并且在主管树中有各种方法来处理这种情况。

Lukas 是对的,因为 SASL 只是报告了进程崩溃的事实。这可以防止您的回调被调用,因此它无法处理崩溃。事实上,它无法处理崩溃,因为它特别依赖于被崩溃的进程调用。

没有看到您的 inets 进程是如何启动的以及进行调用的代码 很难告诉您处理崩溃的正确位置是在您的主管树中。我建议阅读 Erlang 系统设计文档:http : //www.erlang.org/doc/design_principles/users_guide.html 以了解如何使用和处理 erlang 进程。

于 2010-04-25T01:09:00.317 回答
0

inets HTTP 客户端有一个相当不一致的接口。我建议改用lhttpc

于 2010-04-26T12:30:21.420 回答