2012-06-15 61 views
0

我已經採用了牛仔示例代碼並對其進行了說明。Erlang的錯誤報告

的默認請求處理程序的代碼是這樣的:

-module(default_handler). 
-behaviour(cowboy_http_handler). 
-export([init/3, handle/2, terminate/2]). 

init({_Any, http}, Req, []) -> 
    {ok, Req, undefined}. 

handle(Req, State) -> 
    {ok, Req2} = cowboy_http_req:reply(200, [], <<"Hello world!">>, Req), 
    {ok, Req2, State}. 

terminate(_Req, _State) -> 
    ok. 

其直線前進,但我想讓迴文件,所以我把它改爲:

-module(default_handler). 
-behaviour(cowboy_http_handler). 
-export([init/3, handle/2, terminate/2]). 

init({_Any, http}, Req, []) -> 
    {ok, Req, undefined}. 

handle(Req, State) -> 
    try 
    {Path, Req1} = cowboy_http_req:path(Req), 
    {ok, File} = file:read_file(Path), 
    cowboy_http_req:reply(200, [], File, Req1) 
    of 
    {ok, Req2} -> 
     {ok, Req2, State} 
    catch 
    _ -> 
     {ok, Req3} = cowboy_http_req:reply(200, [], <<"Hello world!">>, Req), 
     {ok, Req3, State} 
    end. 

terminate(_Req, _State) -> 
    ok. 

在try-catch事情應該處理這樣一個事實,即可能沒有文件,但事實並非如此。這是爲什麼?

當我試圖獲取一個不存在的文件時,我在控制檯中得到一個大的錯誤報告,誰能告訴我爲什麼?

=ERROR REPORT==== 15-Jun-2012::14:24:54 === 
** Handler default_handler terminating in handle/2 
    for the reason error:{badmatch,{error,badarg}} 
** Options were [] 
** Handler state was undefined 
** Request was [{socket,#Port<0.1515>}, 
       {transport,cowboy_tcp_transport}, 
       {connection,keepalive}, 
       {pid,<0.1175.0>}, 
       {method,'GET'}, 
       {version,{1,1}}, 
       {peer,undefined}, 
       {host,[<<"localhost">>]}, 
       {host_info,undefined}, 
       {raw_host,<<"localhost">>}, 
       {port,8080}, 
       {path,[<<"favicon.ico">>]}, 
       {path_info,undefined}, 
       {raw_path,<<"/favicon.ico">>}, 
       {qs_vals,undefined}, 
       {raw_qs,<<>>}, 
       {bindings,[]}, 
       {headers, 
        [{'Accept-Charset',<<"ISO-8859-1,utf-8;q=0.7,*;q=0.3">>}, 
        {'Accept-Language',<<"en-US,en;q=0.8">>}, 
        {'Accept-Encoding',<<"gzip,deflate,sdch">>}, 
        {'User-Agent', 
         <<"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.19 (KHTML, like Gecko) Ubuntu/10.10 Chromium/18.0.1025.151 Chrome/18.0.1025.151 Safari/535.19">>}, 
        {'Accept',<<"*/*">>}, 
        {'Connection',<<"keep-alive">>}, 
        {'Host',<<"localhost">>}]}, 
       {p_headers,[{'Connection',[<<"keep-alive">>]}]}, 
       {cookies,undefined}, 
       {meta,[]}, 
       {body_state,waiting}, 
       {buffer,<<>>}, 
       {resp_state,waiting}, 
       {resp_headers,[]}, 
       {resp_body,<<>>}, 
       {onresponse,undefined}, 
       {urldecode,{#Fun<cowboy_http.urldecode.2>,crash}}] 
** Stacktrace: [{default_handler,handle,2, 
           [{file,"src/default_handler.erl"},{line,13}]}, 
       {cowboy_http_protocol,handler_handle,3, 
             [{file,"src/cowboy_http_protocol.erl"}, 
             {line,298}]}] 

回答

1

這條線:

{Path, Req1} = cowboy_http_req:path(Req), 

實際返回的二進制文件的列表,如[< < 「路徑」 >>,< < 「路徑2」 >>],而不是像「/路徑/路徑「這應該是你實際上在尋找的東西。

因此,形成文件系統路徑:

{Path, Req1} = cowboy_http_req:path(Req), 
FsPath = lists:foldl(
    fun(PathComponent, Acc) -> 
     string:join([Acc, erlang:binary_to_list(PathComponent)], "/") 
    end, 
    "", 
    Path 
), 
{ok, File} = file:read_file(FsPath), 

(你得到badarg錯誤是因爲參數文件:READ_FILE/1不是一個字符串(列表),但二進制文件的列表,這不是預期的說法

和卡需要_ :。 _條款,就像哈拉爾回答狀態

乾杯

+0

是不是_:_的東西可選? –

2

,可能是因爲它是如何計算的catch子句,見http://www.erlang.org/doc/reference_manual/expressions.html#try

如果Exprs的評估過程中出現異常,但有正確的類沒有匹配ExceptionPattern有一個真正的後衛序列中,異常被傳遞,就好像Exprs沒有被包含在try表達式中一樣。

如果不是查找默認值,則需要指定錯誤class(錯誤,拋出或退出),這是拋出。

try Exprs of 
    Pattern1 [when GuardSeq1] -> 
     Body1; 
    ...; 
    PatternN [when GuardSeqN] -> 
     BodyN 
catch 
    [Class1:]ExceptionPattern1 [when ExceptionGuardSeq1] -> 
     ExceptionBody1; 
    ...; 
    [ClassN:]ExceptionPatternN [when ExceptionGuardSeqN] -> 
     ExceptionBodyN 

一個包羅萬象的,錯誤將寫作如何同時指定類和ExpressionPattern爲「不關心」

catch 
    _:_ -> 

通知。

希望這會有所幫助,因爲我直到現在才'涉足'erlang。 :)

+0

[]並不意味着在這種情況下類的東西是可選的? –

+2

它的確如此,但是如果你省略了erlang這個類的假設是 –