2012-06-15 2 views
0

J'ai pris le code d'exemple de cow-boy et je l'ai reconnu.Rapports d'erreur dans Erlang

Le code pour le gestionnaire de requête par défaut ressemblait à ceci:

-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. 

son avant droit, mais je voulais faire des fichiers de retour donc je l'ai changé:

-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. 

Le try-catch chose devrait gérer le fait qu'il pourrait ne pas y avoir de fichier, mais ce n'est pas le cas. Pourquoi donc?

Lorsque j'essaie d'aller chercher un fichier qui n'est pas là, je reçois un rapport d'erreur important dans la console, quelqu'un peut-il me dire pourquoi?

=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}]}] 

Répondre

1

Cette ligne:

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

retourne en fait une liste des binaires, comme [< < "chemin" >>, < < "path2" >>] au lieu de quelque chose comme «/chemin/path2 "Ce qui devrait être ce que vous cherchez réellement.

Ainsi, pour former le chemin du système de fichiers:

{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), 

(L'erreur de badarg que vous obtenez est parce que l'argument de fichier: read_file/1 n'est pas une chaîne (une liste), mais une liste de binaires , qui est l'argument attendu

Et les prises a besoin d'un _ :.. _ clause, comme Harald Etats réponse

Vive

.
+0

n'est pas le _: _ chose optionnel? –

2

probablement à cause de la façon dont il évalue la clause catch, voir http://www.erlang.org/doc/reference_manual/expressions.html#try

Si une exception se produit lors de l'évaluation de Exprs, mais il n'y a pas ExceptionPattern correspondant de la classe droite avec une véritable séquence de garde, la exception est transmise comme si Exprs n'avait pas été inclus dans une expression try.

Vous devez spécifier une erreur class (erreur, lancer ou sortie) sinon la recherche de la valeur par défaut, ce qui est un jet.

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

un serait écrit erreurs de fourre-tout- comme

catch 
    _:_ -> 

Remarquez comment vous spécifiez à la fois classe et ExpressionPattern comme "ne se soucient pas".

Espérons que cela aide parce que je n'ai «bavé» dans erlang jusqu'à maintenant. :)

+0

ne signifie pas que la chose de classe est facultative dans ce cas? –

+2

il le fait, mais si vous omettez la classe erlang suppose qu'il est lancer –