在咱們的項目中,不少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),
先總結到這,如今只碰到這些運行時的崩潰,在遇到別的接着總結,未完待續......