Erlang 终止原因:没有与jlib:iq_到_xml匹配的函数子句

Erlang 终止原因:没有与jlib:iq_到_xml匹配的函数子句,erlang,ejabberd,Erlang,Ejabberd,我已经为ejabberd编写了一个iq处理程序模块,它接受一个iq查询,并且应该返回更新了相关元素的iq记录。我已经在这两天没有决议,所以我张贴在这里的帮助 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 th

我已经为ejabberd编写了一个iq处理程序模块,它接受一个iq查询,并且应该返回更新了相关元素的iq记录。我已经在这两天没有决议,所以我张贴在这里的帮助

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.
process_local_iq(_From,To,#iq{type=type,sub_el=SubEl}=iq)->
?INFO_MSG(“处理本地IQ类型=~p~n SubEl=~p~n IQ=~p~n”,[Type,SubEl,IQ]),
%%通过测试JID的用户id部分是否为空,检查服务器名是否为TO
如果要#jid.luser==->
%%获取iq请求的ID
%%Id=IQ#IQ.Id,
%%从sub_el中取出子类型并放入variable SubType
SubType=proplist:get_值(,IQ#IQ.sub#el#xmllel.attrs),
?INFO_MSG(“处理本地IQ获取-子类型=~p~n”,[SubType]),
案例类型
设置->
%%将新用户添加到jid_用户表或更新当前用户表
如果子类型==->
%%使用Userid并更新jid_用户表
?信息信息(“处理本地IQ集-更新”,[]),
IQ#IQ{type=error,sub_el=[SubEl,?ERR_NOT_ALLOWED]}
完,,
如果子类型==->
%%将新记录写入数据库表jid_user
?信息信息(“处理本地IQ集-新”,[]),
IQ#IQ{type=error,sub_el=[SubEl,?ERR_NOT_ALLOWED]}
完,,
%%从#iq主体中获取类型并进行测试
?信息信息(“处理本地IQ集”,[]),
IQ#IQ{type=error,sub_el=[SubEl,?ERR_NOT_ALLOWED]};
获取->
%%检查用户ID的可用性或检索已知用户信息
%%从xml数据包中获取用户id
Childrenrec=IQ#IQ.sub#el#xmllel.儿童,
Attrib=IQ#IQ.sub#el#xmllel.attrs,
[Childrenrec]),
SubRec=proplist:lookup(xmlel,Childrenrec),
KList=子目录#xmllel.children,
UserId=proplist:get_值(xmlcata,KList),
病例亚型
->
%%使用Userid并从jid_user表中检索记录
?INFO_MSG(“处理本地IQ获取检索-UserId=~p~n”,[UserId]),
FR=fun()->
case Rec=mnesia:read({jid_users,UserId})=::=[]的
true->%%用户id可供使用,因此使用状态更新iq记录
IQ#IQ{type=result,sub#el=[#xmlel{name=,attrs=Attrib,children=[{xmlcata,“未找到记录”}]};
false->%找到记录,因此请使用数据填充xml结构
%%Rec1=列表:最后一个(Rec),
XmlStruct=item_to_xml(Rec#jid_users{}),%%将记录转换为xml
IQ#IQ{type=result,sub#el=[#xmlel{name=,attrs=[],children=[XmlStruct]}]
结束
完,,
mnesia:交易(FR);
->
%%检查请求的用户id是否可用
?INFO_MSG(“处理本地IQ获取检查-UserId=~p~n”,[UserId]),
%%用户id并检查mnesia表jib_用户
FC=fun()->
案例mnesia:read({jid_users,UserId})=:=[]的
true->%%用户id可供使用,因此使用状态更新iq记录
**Test=IQ#IQ{type=result,sub#el=[#xmlel{name=,attrs=Attrib,children=[#xmlel{name=,attrs=],children=[{xmlcata,}]}**
?INFO_MSG(“处理本地IQ获取检查-测试=~p~n”,[Test]),
试验;
false->%%用户Id已被使用
IQ{type=result,sub#el=[{name=,children=[{{name=,attrs=],children=[{xmlcata,“不可用”}]}
%%IQ#IQ{type=result,sub#el=[\xmlel{name=,attrs=[],children=[{xmlcata,“不可用”}]}
结束
完,,
mnesia:交易(FC)
结束
结束;
正确->
%%返回并清空主体设置为某个值的记录
?信息信息(“处理本地IQ集-提供完整JID”,[]),
IQ#IQ{type=error,sub_el=[SubEl,?ERR_NOT_ALLOWED]}
结束。
这行代码出现故障:

  Test =IQ#iq{type = result, sub_el = [#xmlel{name = <<"query">>, attrs = Attrib, children = [#xmlel{name = <<"userid">>, attrs = [], children=[{xmlcdata, <<"available">>}]}]}]},
Test=IQ#IQ{type=result,sub#el=[#xmlel{name=,attrs=Attrib,children=[#xmlel{name=,attrs=],children=[{xmlcata,}]},
出现此错误(在日志中):

2016-03-13 23:51:44.923[错误]gen_服务器终止原因:没有与jlib:iq_to_xml({atomic,{iq,,result,,{xmlel,,[{,},{,},{,},},}匹配的函数子句)第463行
2016-03-13 23:51:44.923[错误]0个邻居的崩溃报告进程退出,原因是:gen_服务器中没有与jlib:iq_to_xml({atomic,{iq,,result,,{xmlel,,[{,},{,{,},},},…}})行463匹配的函数子句:terminate/7行804
2016-03-13 23:51:44.923[错误]主管ejabberd_iq_sup的子项未定义从退出时的{gen_iq_handler,start_link,undefined}行开始,原因是没有与jlib:iq_to_xml({atomic,{iq,result,{xmlel,,[{,},{,},{,},{,},{,},},},},…}})匹配的函数子句在上下文子项中终止
这是客户端发送并由iq处理程序接收的输入iq:

  IQ={iq,<<"MX_4">>,get,<<"user:profile">>,<<>>,{xmlel,<<"query">>,[{<<"xmlns">>,<<"user:profile">>},{<<"type">>,<<"CHECK">>}],[{xmlel,<<"userId">>,[],[{xmlcdata,<<"wilford">>}]}]}}
IQ={IQ,,get,,,{xmllel,,[{,},{,},{xmllel,,[],[{xmlcata,}]}
希望我已经发布了足够的信息

问候,


Will

您应该直接从该函数返回IQ应答,以便ejabberd路由它

相反,您将返回调用
mnesia:transaction/1
的结果,其形式为
{atomic,result}
。这不是有效的IQ数据包

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