2012-06-15 3 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-캐치 파일이 없다는 사실을 처리해야하지만 그렇지 않습니다. 왜 그런가요?

거기에없는 파일을 가져 오려고하면 콘솔에 큰 오류 보고서가 표시됩니다. 아무도 그 이유를 알 수 있습니까? 예외가 Exprs의 평가 중에 발생하지만 바로 클래스의 일치 ExceptionPattern 진정한 가드 시퀀스가 ​​없으면 아마 그것 때문에 캐치 절을 평가하는 방법의

=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">>] 대신 "/ 경로 같은의/경로 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

, http://www.erlang.org/doc/reference_manual/expressions.html#try

를 참조하십시오 Exprs가 try 표현식에 포함되지 않은 것처럼 전달됩니다.

기본값 인 throw를 찾지 않으려면 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에서 'dabbled'했기 때문에 이것이 도움이 되길 바랍니다. :)

+0

[이] 경우 클래스 물건이 선택 사항임을 의미하지 않습니다? –

+2

그래도 클래스를 생략하면 erlang이 던져진다고 가정합니다. –