2
votes

my erlang server generates a case_clause error after every request for some reason. Here is my code:
keychain_no_auth_handler.erl

-module(keychain_no_auth_handler).
-export(
  [ init/3, 
    content_types_accepted/2,
    terminate/3,
    allowed_methods/2,
    handle_request/2
  ]).

-export([is_registered/1]).

init(_Transport, _Req, []) -> {upgrade, protocol, cowboy_rest}.

terminate(_Reason, _Req, _State) -> ok.

allowed_methods(Req, State) -> {[<<"POST">>], Req, State}.

content_types_accepted(Req, State) -> {[{<<"application/json">>, handle_request}], Req, State}.

handle_request(Req, State) ->
    {Action, Req2} = cowboy_req:binding(action, Req),

    {Reply, Req3} = case Action of
        <<"registered">> -> is_registered(Req2)
    end,

    {ok, Req4} = cowboy_req:reply(200, [{<<"content-type">>, <<"application/json">>}], Reply, Req3),
   {ok, Req4, State}
.

is_registered(Req) ->
    {Number, Req2} = cowboy_req:qs_val(<<"number">>, Req),
    Reply = backend:is_registered(Number),
    {Reply, Req2}
.

is_registered [function]

is_registered(Number) ->
    emysql:prepare(is_registered, <<"SELECT `device`.`id` FROM `device` WHERE `device`.`number`= ?">>),
    ResultPacket = emysql:execute(auth_pool, is_registered, [Number]),
    ResultType = is_record(ResultPacket, result_packet),

    case ResultType of
        true -> 
            Field = emysql_util:as_proplist(ResultPacket),
            Id = proplists:get_value(<<"device.id">>, Field),
            Registered = Id >= 0,

            case Registered of
                true -> 
                    Reply = {[{response, registered}]},
                    jiffy:encode(Reply)
                ;
                false -> 
                    Reply = {[{response, available}]},
                    jiffy:encode(Reply)
            end;
        false -> 
            Reply = {[{response, error}]},
            jiffy:encode(Reply)
    end
.

The server replies with the appropriate response and then generates a case_clause error after every request:

=ERROR REPORT==== 5-Feb-2014::10:32:39 === Error in process <0.182.0> on node 'keychain@dnldd' with exit value: {{case_clause,{ok,{http_req,#Port<0.2286>,ranch_tcp,keepalive,<0.182.0>,<<4 bytes>>,'HTTP/1.1',{{127,0,0,1},49720},<<9 bytes>>,undefined,4004,<<11 bytes>>,undefined,<<0 bytes>>,[],[{action,<<10 bytes>>}],[{<<4 bytes>>,<<14 bytes>>},{<<10 bytes>>,<<10 bytes>>},{<<14 bytes>>,<<1 byte>>},{<<13 bytes>>,<<8 bytes>>},{<<6 bytes>>,<<51 bytes>>},{<<6 bytes>>,<<12 bytes>>},{<<12 bytes>>,<<16 bytes>>},{<<10 bytes>>,<<120 bytes>>},{<<13 bytes>>,<<36 bytes>>},{<<6 bytes>>,<<3 bytes>>},{<<3 bytes>>,<<1 byte>>},{<<15 bytes>>,<<17 bytes>>},{<<15 bytes>>,<<14 bytes>>}],[{<<12 bytes>>,{<<11 bytes>>,<<4 bytes>>,[]}},{<<17 bytes>>,undefined},{<<13 bytes>>,undefined},{<<19 bytes>>,undefined},{<<8 bytes>>,undefined},{<<6 bytes>>,[...

=ERROR REPORT==== 5-Feb-2014::10:32:39 === Ranch listener keychain_http had connection process started with cowboy_protocol:start_link/4 at <0.182.0> exit with reason: {{case_clause,{ok,{http_req,#Port<0.2286>,ranch_tcp,keepalive,<0.182.0>,<<"POST">>,'HTTP/1.1',{{127,0,0,1},49720},<<"127.0.0.1">>,undefined,4004,<<"/registered">>,undefined,<<>>,[],[{action,<<"registered">>}],[{<<"host">>,<<"127.0.0.1:4004">>},{<<"connection">>,<<"keep-alive">>},{<<"content-length">>,<<"0">>},{<<"cache-control">>,<<"no-cache">>},{<<"origin">>,<<"chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop">>},{<<"number">>,<<"233265256262">>},{<<"content-type">>,<<"application/json">>},{<<"user-agent">>,<<"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36">>},{<<"postman-token">>,<<"61b7c8f0-b4f8-3bde-8b99-67c141242e5a">>},{<<"accept">>,<<"/">>},{<<"dnt">>,<<"1">>},{<<"accept-encoding">>,<<"gzip,deflate,sdch">>},{<<"accept-language">>,<<"en-US,en;q=0.8">>}],[{<<"content-type">>,{<<"application">>,<<"json">>,[]}},{<<"if-modified-since">>,undefined},{<<"if-none-match">>,undefined},{<<"if-unmodified-since">>,undefined},{<<"if-match">>,undefined},{<<"accept">>,[{{<<"">>,<<"">>,[]},1000,[]}]},{<<"connection">>,[<<"keep-alive">>]}],undefined,[{charset,undefined},{media_type,{<<"text">>,<<"html">>,[]}}],waiting,undefined,<<>>,true,done,[],<<>>,undefined},undefined}},[{cowboy_rest,process_content_type,3,[{file,"src/cowboy_rest.erl"},{line,780}]},{cowboy_protocol,execute,4,[{file,"src/cowboy_protocol.erl"},{line,529}]}]}

What am I doing wrong here? Thanks.

2

2 Answers

3
votes

I figured it out, needed to set the response for the request and return it. cowboy_rest handles the actual reply automatically.

handle_request(Req, State) ->
    {Action, Req2} = cowboy_req:binding(action, Req),

    {Reply, Req3} = case Action of
        <<"registered">> -> is_registered(Req2)
    end,

    Req3 = cowboy_req:set_resp_body(Reply, Req3),
    {true, Req2, State}
.
0
votes

Try changing return tuple in your handle_request from:

{ok, Req, State}

to:

{true, Req, State}