2016-03-15 31 views
1

我已經爲ejabberd編寫了一個iq處理程序模塊,它需要一個iq查詢,並且應該返回更新了相關元素的iq記錄。我一直沒有解決這個問題2天,所以我在這裏發佈求助。以原因終止:沒有函數子句匹配jlib:iq_to_xml

process_local_iq(_From, To, #iq{type = Type, sub_el = SubEl} = IQ) -> 
?INFO_MSG("PROCESS LOCAL IQ Type=~p ~n SubEl =~p ~n IQ=~p~n", [Type, SubEl, IQ]), 
%%Check that the server name is the TO by testing the emptiness of the user id part of the JID 
if To#jid.luser == <<"">> -> 
    %%Get the ID for the iq request 
    %%Id=IQ#iq.id, 

    %%Take out the subTypes from the sub_el and Place in variable SubType 
    SubType = proplists:get_value(<<"type">>, IQ#iq.sub_el#xmlel.attrs), 
    ?INFO_MSG("PROCESS LOCAL IQ GET - SubType = ~p~n", [SubType]), 
    case Type of 
    set -> 
     %%Add the NEW user to the jid_user table OR UPDATE the current one 
     if SubType== <<"UPDATE">> -> 
     %% Use the Userid and update the jid_user table 
     ?INFO_MSG("PROCESS LOCAL IQ SET - UPDATE", []), 
     IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} 

     end, 

     if SubType == <<"NEW">> -> 
     %% Write the new record to the database - table jid_user 
     ?INFO_MSG("PROCESS LOCAL IQ SET - NEW", []), 
     IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} 
     end, 

     %%Get the type from the #iq body and test it 
     ?INFO_MSG("PROCESS LOCAL IQ SET", []), 
     IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; 


    get -> 
     %%Either CHECK the availability of a userid OR RETRIEVE a known user information 
     %% Get the user id from the xml packet 
     Childrenrec = IQ#iq.sub_el#xmlel.children, 
     Attrib = IQ#iq.sub_el#xmlel.attrs, 
     [Childrenrec]), 
     SubRec = proplists:lookup(xmlel, Childrenrec), 

     KList = SubRec#xmlel.children, 

     UserId = proplists:get_value(xmlcdata, KList), 

     case SubType of 
      <<"RETRIEVE">> -> 
        %% Use the Userid and retrieve the record from the jid_user table 
        ?INFO_MSG("PROCESS LOCAL IQ GET RETRIEVE - UserId = ~p~n", [UserId]), 
        FR = fun() -> 
           case Rec = mnesia:read({jid_users, UserId}) =:= [] of 
            true -> %% User id is available for use so update the iq record with the status 
            IQ#iq{type = result, sub_el = [#xmlel{name = <<"query">>, attrs = Attrib, children = [{xmlcdata, "RECORD NOT FOUND"}]}]}; 

            false -> %% Record found so use the data populate the xml structure 
            %%Rec1 = lists:last(Rec), 
            XmlStruct = item_to_xml(Rec#jid_users{}), %%Convert the record to XML 
            IQ#iq{type = result, sub_el = [#xmlel{name = <<"query">>, attrs = [], children = [XmlStruct]}]} 
           end 
        end, 
        mnesia:transaction(FR); 

      <<"CHECK">> -> 
        %% Check if the requested user id is available 
        ?INFO_MSG("PROCESS LOCAL IQ GET CHECK - UserId = ~p~n", [UserId]), 
        %%User the id and check the mnesia table jib_user 
        FC = fun() -> 
           case mnesia:read({jid_users, UserId}) =:= [] of 
            true -> %% User id is available for use so update the iq record with the status 
             **Test =IQ#iq{type = result, sub_el = [#xmlel{name = <<"query">>, attrs = Attrib, children = [#xmlel{name = <<"userid">>, attrs = [], children=[{xmlcdata, <<"available">>}]}]}]},** 
             ?INFO_MSG("PROCESS LOCAL IQ GET CHECK - Test= ~p~n", [Test]), 
             Test; 

            false -> %% User Id already being used 
             IQ#iq{type = result, sub_el = [#xmlel{name = <<"query">>, children = [{#xmlel{name = <<"userid">>, attrs = [], children=[{xmlcdata, "NOT AVAILABLE"}]}}]}]} 
            %% IQ#iq{type = result, sub_el = [#xmlel{name = <<"query">>, attrs = [], children = [{xmlcdata, "NOT AVAILABLE"}]}]} 
           end 
        end, 
        mnesia:transaction(FC) 
     end 

    end; 
true -> 
    %%Return and empty record with body set to some value 
    ?INFO_MSG("PROCESS LOCAL IQ SET - FULL JID SUPPLIED", []), 
    IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} 

end. 

的這行代碼failling:

Test =IQ#iq{type = result, sub_el = [#xmlel{name = <<"query">>, attrs = Attrib, children = [#xmlel{name = <<"userid">>, attrs = [], children=[{xmlcdata, <<"available">>}]}]}]}, 

利用該錯誤(在日誌):

2016-03-13 23:51:44.923 [error] <0.421.0> gen_server <0.421.0> terminated with reason: no function clause matching jlib:iq_to_xml({atomic,{iq,<<>>,result,<<>>,<<>>,{xmlel,<<"query">>,[{<<"xmlns">>,<<"user:profile">>},{<<"type">>,...}],...}}}) line 463 
2016-03-13 23:51:44.923 [error] <0.421.0> CRASH REPORT Process <0.421.0> with 0 neighbours exited with reason: no function clause matching jlib:iq_to_xml({atomic,{iq,<<>>,result,<<>>,<<>>,{xmlel,<<"query">>,[{<<"xmlns">>,<<"user:profile">>},{<<"type">>,...}],...}}}) line 463 in gen_server:terminate/7 line 804 
2016-03-13 23:51:44.923 [error] <0.349.0> Supervisor ejabberd_iq_sup had child undefined started with {gen_iq_handler,start_link,undefined} at <0.421.0> exit with reason no function clause matching jlib:iq_to_xml({atomic,{iq,<<>>,result,<<>>,<<>>,{xmlel,<<"query">>,[{<<"xmlns">>,<<"user:profile">>},{<<"type">>,...}],...}}}) line 463 in context child_terminated 

這是輸入IQ由客戶機發送和接收由iq處理程序:

IQ={iq,<<"MX_4">>,get,<<"user:profile">>,<<>>,{xmlel,<<"query">>,[{<<"xmlns">>,<<"user:profile">>},{<<"type">>,<<"CHECK">>}],[{xmlel,<<"userId">>,[],[{xmlcdata,<<"wilford">>}]}]}} 

H我已經發布了足夠的信息。

問候,

請問

回答

1

您應該直接從功能,使其得到由ejabberd路由進行恢復智商的答覆。

取而代之,您將返回形式爲{atomic, Result}的呼叫mnesia:transaction/1的結果。這不是有效的IQ數據包。

因此,您需要展開mnesia事務結果以移除周圍的元組{atomic,Result}才能返回結果。

+1

是的,這是問題所在。我仍然不確定我是怎麼看的,但再次感謝。 – WXM1967