2012-06-15 64 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这个类的假设是 –