鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 编程语言开发 > erlang > >

Cowboy 源码分析(二十三)

来源:互联网 作者:佚名 时间:2012-11-15 13:44
大家好,上一篇在文章的最后我们提到 cowboy_http_protocol: terminate_request/3 函数,今天我们继续往下看: -spec terminate_request(any(), #http_req{}, #state{}) - ok.terminate_request(HandlerState, Req, State) - HandlerRes = handler_terminate

  大家好,上一篇在文章的最后我们提到cowboy_http_protocol:terminate_request/3 函数,今天我们继续往下看:

-spec terminate_request(any(), #http_req{}, #state{}) -> ok. terminate_request(HandlerState, Req, State) -> HandlerRes = handler_terminate(HandlerState, Req, State), next_request(Req, State, HandlerRes).

  这个函数就两行代码:

  首先调用cowboy_http_protocol:handler_terminate/3 函数:

-spec handler_terminate(any(), #http_req{}, #state{}) -> ok. handler_terminate(HandlerState, Req, #state{handler={Handler, Opts}}) -> try Handler:terminate(Req#http_req{resp_state=locked}, HandlerState) catch Class:Reason -> PLReq = lists:zip(record_info(fields, http_req), tl(tuple_to_list(Req))), error_logger:error_msg( "** Handler ~p terminating in terminate/2~n" " for the reason ~p:~p~n" "** Options were ~p~n** Handler state was ~p~n" "** Request was ~p~n** Stacktrace: ~p~n~n", [Handler, Class, Reason, Opts, HandlerState, PLReq, erlang:get_stacktrace()]) end.

  Handler:terminate(Req#http_req{resp_state=locked}, HandlerState)

  = default_handler:terminate(Req#http_req{resp_state=locked}, HandlerState)

  跟之前类似,调用 default_handler:terminate/2 函数:

terminate(_Req, _State) -> ok.

  简单到不能再简单的函数,当函数正确执行时,返回ok,那么如果是执行函数中有异常,那么cowboy_http_protocol:handler_terminate/3 函数就会捕获到异常。

  我们来做个测试,修改default_handler:terminate/2 函数,让它手动抛出异常,然后来跟踪下代码的执行过程,修改代码如下:

terminate(_Req, _State) -> throw("terminate error."), ok.

  如上面所示,很简单,我们添加了一行代码,throw("terminate error."), 好了,重新编译,然后运行,这里我依然使用Debugger,来断点查看下,运行情况,如下图:

  

  注意:

  < Class = throw
  < Reason = "terminate error."

  接下来,我们看下异常处理的具体逻辑:

catch Class:Reason -> PLReq = lists:zip(record_info(fields, http_req), tl(tuple_to_list(Req))), error_logger:error_msg( "** Handler ~p terminating in terminate/2~n" " for the reason ~p:~p~n" "** Options were ~p~n** Handler state was ~p~n" "** Request was ~p~n** Stacktrace: ~p~n~n", [Handler, Class, Reason, Opts, HandlerState, PLReq, erlang:get_stacktrace()]) end.

  这里有几个系统函数,我们之前没接触过,这里我们按照老规矩,我们来一个一个看下:

  首先是 tuple_to_list/1 函数,这个函数比较常用,香港虚拟主机,erlang doc地址: 从函数命名,应该很容易明白,就是将元组转成列表,下图是官方的解释,以及例子:  

  

  接下来是 tl/1 函数,返回去掉列表中第一个元素的列表,erlang doc地址: 和上面一样,我截了个图,方便大家查看:

  

  然后看下,香港虚拟主机record_info/2 函数参考坚强2002同学的文章:

  下面是我写的测试代码:

  

  大家看看,我想应该能够对这个函数有一定的理解了吧。

  往后就是 lists:zip/2 函数,erlang doc地址: 从网上找的,关于 lists模块中的函数中文解释,地址: 谢谢这位朋友的翻译,下图是该函数的解释,很清楚:

  

  最后是 error_logger:error_msg/2 函数,香港服务器租用,向错误日志发送一个错误消息。它的参数与io:format(Format, Data)函数的参数一样,erlang doc 地址:

  

  最后是我们可以从看到的错误信息

  

  

  好了,这个函数就讲到这里。

  下一篇,我们将从 cowboy_http_protocol:terminate_request/3 函数的这一行继续往下看:next_request(Req, State, HandlerRes).

  最后,谢谢大家支持,晚安。

网友评论
<