Erlang運行時崩潰錯誤總結及排查

        在咱們的項目中,不少Erlang程序編譯能夠經過,可是運行的時候就崩潰了,不過他很友好,通常會顯示錯誤的行號和錯誤緣由,以前不會看系統打印出的錯誤信息,致使錯誤排查很是慢,如今對我遇到的錯誤提示信息進行分類和總結,這樣之後咱們出錯了,就能夠更迅速的解決。php

1. 錯誤緣由- case_clausejava

崩潰信息以下:json

這個錯誤 - case_clause,是因爲分支匹配出了問題,代碼以下;dom

case lists:keyfind(<<"meetingID">>, 1, QueryValues) of
    {_Name, MeetingID} ->  %%注意這兒
        lager:info("The meeting id is : ~p~n",[MeetingID]),
        case lists:keyfind(<<"type">>, 1, QueryValues) of
           {_Name, Type} -> %%注意這兒
              getmeetingterminal( binary_to_list(MeetingID), binary_to_list(Type), Req2 );
              false -> 
              lager:error("There are no meeting type in query string!~n"),
               cowboy_req:reply( 400,
                      [  
                        {<<"content-type">>, <<"text/plain">>}
                  ], <<"There are no meeting type in query string! ">>, Req2 )
        end;
    false -> 
        lager:error("There are no meeting id in query string!~n"),
        cowboy_req:reply( 400,
          [  
            {<<"content-type">>, <<"text/plain">>}
          ], <<"There are no meeting id in query string! ">>, Req2 )
end;

衝突的兩句代碼以下:函數

  {_Name, MeetingID} ->
  
     {_Name, Type} ->

能夠看到第一個case的第一分支有一個_Name的變量,這個變量的做用域在這個分支中,與第二個case的第一個分支照樣的有_Name的變量,衝突了,由於第二個case語句整個都是第一個case的第一個分支中,由於Erlang裏面只能夠一次綁定,其實就是不匹配,可是咱們能夠去找定位到分支上找。spa

2.錯誤緣由-badmatchcode

就是模式匹配錯誤,代碼以下:orm

getmeetingterminal( MeetingID,Type, Req ) ->
   case TerminalList of
         [] ->
             lager:info("The terminal list is empty!~n"),
             cowboy_req:reply( 204, Req );
          _ ->
              Fun = fun( E164, Acc ) ->
                  case nms_cache:get_terminal_base_info_by_e164(E164) of
                     {error,_} ->
                          Acc;
                      {ok,{DevMoid,_,Name,E164}} ->
                         {ok,Type} = nms_cache:get_terminal_running_info(DevMoid,"type"),
                         {ok,Version} = nms_cache:get_terminal_running_info(DevMoid,"version"),
                          {ok,IP} = nms_cache:get_terminal_net_info(DevMoid,"ip"),
                          [{DevMoid,Name,E164,IP,Type,Version}|Acc]
                   end
                end;
end.


咱們能夠看到Type衝突了,由於第一個Type的做用域是整個函數。能夠看到緣由是badmatch,因此通常找等號(就是模式匹配)就能夠很快的排錯。ip

這兩句衝突的代碼以下:作用域

getmeetingterminal( MeetingID,Type, Req ) ->

 {ok,Type} = nms_cache:get_terminal_running_info(DevMoid,"type"),

總之,運行的時候的錯誤通常是一個變量進行了兩次綁定,這在Erlang裏面是不行的,因此咱們對Erlang的變量的做用域必定要很清楚,這樣纔不會讓一個變量兩次綁定了。

3.錯誤 - badarg

這個你傳遞的參數不符合別人接收參數的類型,

看崩潰信息提示,就是在2225行,list_to_binary函數的參數有問題,有一個參數爲<<"">>

ResolveTimeStr = case ResolveTime of
    undefined ->
        <<"">>;
    {datetime,Time} ->
        %%time_util:date_to_str(Time)
        time_util:beijingTimeToSet(Time,ZoneNumber,Offset,date_to_str)
 end,
 
WarningObj = {obj,[{"deviceMoid",ServerMoid},
                   {"deviceName",ServerName},
       {"deviceType",ServerSubType},
       {"deviceIP",IP},
       {"domainMoid",DomainMoid},
       {"domainName",DomainName},
       {"level",Level},
       {"description", Description},
       {"starttime",list_to_binary(StartTimeStr)},
2225   {"resolvetime",list_to_bianry(ResolveTimeStr)} %%注意就是這一行
    ]},
[WarningObj|Acc]

咱們能夠看獲得第2225行的代碼爲

 {"resolvetime",list_to_bianry(ResolveTimeStr)}

而ResolveTimeStr的值咱們看上面的代碼知道它有兩種類型的值,list和binary,因此把binary傳給list_to_binary會出現崩潰。

4. 錯誤 undef

這個錯誤是沒有定義的意思

錯誤提示信息以下:

從提示能夠看出rfc4627:encode這個函數沒有定義。

代碼以下:

UserLogObjList = formatUserlogobj( UserLogList, Req ),
lager:info("Begin encode all user log json data!~n"),
JSON = rfc4627:encode( UserLogObjList,Req),
Req2 = cowboy_req:set_resp_body( JSON, Req ),

能夠看到一下這就代碼調用的時候,多謝了一個參數Req.

JSON = rfc4627:encode( UserLogObjList,Req),

先總結到這,如今只碰到這些運行時的崩潰,在遇到別的接着總結,未完待續......

相關文章
相關標籤/搜索