节相关的错误处理的方式类似流错误流错误, 但是不像流错误那样,节错误是可恢复的; 所以, 他们不会导致XML和当前TCP连接的中止. 反之, 发现错误条件的实体返回一个错误节, 它是一个这样的节:
以下规则适用于节错误:
节相关的错误的语法如下, 这里展示的用方括号'['和']'括起来的XML数据是可选的, 'intended-recipient' 是原始节指定的地址的那个实体的JID, 'sender' 是原始实体的JID, 而 'error-generator' 是检测到错误的并方会错误节的那个实体.
<stanza-kind from='intended-recipient' to='sender' type='error'> [OPTIONAL to include sender XML here] <error [by='error-generator'] type='error-type'> <defined-condition xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> [<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' xml:lang='langcode'> OPTIONAL descriptive text </text>] [OPTIONAL application-specific condition element] </error> </stanza-kind>
"stanza-kind"必须是 message, presence, 或 iq 之一.
"error-type" 必须是以下之一:
"defined-condition"必须符合8.3.3定义的节错误条件之一. 然而, 因为将来可能会发生额外的错误条件, 如果实体接受到一个它不理解的节错误条件,那么它必须把这个未知的条件当成<undefined-condition/> (8.3.3.21). 如果一个XMPP协议扩展的设计者或一个XMPP实现的开发者需要未在本协议中定义的节错误条件的通讯, 他们可以定义应用特有的命名空间所限定的应用特有的错误条件元素来实现这个目标.
<error/>元素:
<text/>元素是可选的. 如果包含了它, 它仅被用于提供描述和诊断信息以补充说明已定义条件或应用特有的条件的含义. 它不能(MUST NOT)被应用程序当成编程信息来解释. 它不应该被用于向自然人用户展示错误消息, 但是可以被附加在该已定义条件元素(以及, 可选的, 应用特有的条件元素)的错误消息上展示.
以下条件是已定义好用于节错误的.
error-type 的值是被推荐用于每个已定义的条件通常预期的类型; 无论如何, 在某些情况下不同的类型可能更合适.
发送者发送的节里包含的XML不符合适当的schema或不能被拥有(例如, IQ节的'type'属性包含一个不能识别的值, 或一个被已知的命名空间限定的元素但是违反了该元素的已定义的语法); 相关的错误类型应该是"modify".
C: <iq from='[email protected]/balcony' id='zj3v142b' to='im.example.com' type='subscribe'> <ping xmlns='urn:xmpp:ping'/> </iq> S: <iq from='im.example.com' id='zj3v142b' to='[email protected]/balcony' type='error'> <error type='modify'> <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </iq>
访问未被授权,因为一个现存的资源使用了相同的名字或地址; 相关的错误类型应该是"cancel".
C: <iq id='wy2xa82b4' type='set'> <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'> <resource>balcony</resource> </bind> </iq> S: <iq id='wy2xa82b4' type='error'> <error type='cancel'> <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </iq>
出现在XML节里的特性没有被预定的接收方或中间服务器实现,所以该节无法被处理(例如, 该实体知道该命名空间但是不认识元素名); 相关的错误类型应该是"cancel" 或 "modify".
C: <iq from='[email protected]/balcony' id='9u2bax16' to='pubsub.example.com' type='get'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <subscriptions/> </pubsub> </iq> E: <iq from='pubsub.example.com' id='9u2bax16' to='[email protected]/balcony' type='error'> <error type='cancel'> <feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> <unsupported xmlns='http://jabber.org/protocol/pubsub#errors' feature='retrieve-subscriptions'/> </error> </iq>
请求的实体没有必要的许可来执行一个只允许特定授权角色或个体来完成的动作(即, 它通常和授权而不是验证有关); 相关的错误类型应该是"auth".
C: <presence from='[email protected]/balcony' id='y2bs71v4' to='[email protected]/JulieC'> <x xmlns='http://jabber.org/protocol/muc'/> </presence> E: <presence from='[email protected]/JulieC' id='y2bs71v4' to='[email protected]/balcony' type='error'> <error type='auth'> <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </presence>
接收者或服务器无法再用这个地址联系到, 通常是永久意义上的(和<redirect/>错误条件相反, 它被用于临时的地址失败); 相关的错误类型应该是"cancel"并且该错误节应该包含一个新的地址(如果可用的话)作为<gone/>元素的XML字符串数据(它必须是一个实体可以联系的唯一资源标识符URI或国际化资源标识符IRI, 典型的是一个XMPP‑URI定义的XMPP IRI.
C: <message from='[email protected]/churchyard' id='sj2b371v' to='[email protected]' type='chat'> <body>Thy lips are warm.</body> </message> S: <message from='[email protected]' id='sj2b371v' to='[email protected]/churchyard' type='error'> <error by='example.net' type='cancel'> <gone xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'> xmpp:[email protected] </gone> </error> </message>
服务器发生了错误的配置或其他阻止它处理改节的内部错误; 相关的错误类型应该是"cancel".
C: <presence from='[email protected]/balcony' id='y2bs71v4' to='[email protected]/JulieC'> <x xmlns='http://jabber.org/protocol/muc'/> </presence> E: <presence from='[email protected]/JulieC' id='y2bs71v4' to='[email protected]/balcony' type='error'> <error type='cancel'> <internal-server-error xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </presence>
找不到请求的JID地址或条目; 相关的错误类型应该是"cancel".
C: <presence from='[email protected]/bar' id='pwb2n78i' to='[email protected]/foo'/> S: <presence from='[email protected]/foo' id='pwb2n78i' to='[email protected]/bar' type='error'> <error type='cancel'> <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </presence>
发送的实体所提供(例如, 在资源绑定的时候)或与之通讯(例如, 一个节的'to'地址)的XMPP地址或其中一部分违反了XMPP‑ADDR定义的规则; 相关的错误类型应该是"modify".
C: <presence from='[email protected]/balcony' id='y2bs71v4' to='ch@r@[email protected]/JulieC'> <x xmlns='http://jabber.org/protocol/muc'/> </presence> E: <presence from='ch@r@[email protected]/JulieC' id='y2bs71v4' to='[email protected]/balcony' type='error'> <error by='muc.example.com' type='modify'> <jid-malformed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </presence>
接收者或服务器理解该请求但是不能处理它,因为该请求不符合该接收者或服务器的标准(例如, 请求订阅信息但是未同时包含接收者需要的配置参数); 相关的错误类型应该是"modify".
C: <message to='[email protected]' id='yt2vs71m'> <body>[ ... the-emacs-manual ... ]</body> </message> S: <message from='[email protected]' id='yt2vs71m'> <error type='modify'> <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </message>
接收者或服务器不允许任何实体执行该动作(例如, 向列入黑名单的域发送消息); 相关的错误类型应该是"cancel".
C: <presence from='[email protected]/balcony' id='y2bs71v4' to='[email protected]/JulieC'> <x xmlns='http://jabber.org/protocol/muc'/> </presence> E: <presence from='[email protected]/JulieC' id='y2bs71v4' to='[email protected]/balcony' type='error'> <error type='cancel'> <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </presence>
发送者在被允许执行某动作之前需要提供凭证, 或已经提供了错误的凭证("not-authorized"的提法, 来源于HTTP的"401 Unauthorized"错误, 可能导致读者认为这个条件是和授权相关的, 但其实它通常用于验证相关的领域); 相关的错误类型应该是"auth".
C: <presence from='[email protected]/balcony' id='y2bs71v4' to='[email protected]/JulieC'> <x xmlns='http://jabber.org/protocol/muc'/> </presence> E: <presence from='[email protected]/JulieC' id='y2bs71v4' to='[email protected]/balcony'> <error type='auth'> <not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </presence>
实体违反了一些本地服务策略(例如, 一个消息包含了服务禁止的单词)而服务器可以选择在<text/>元素里或在应用特有的条件元素里指定策略; 相关的错误类型应该是"modify"或"wait",取决于被违反的策略.
(在下例中, 客户端发送一个包含了根据服务器的本地服务策略被禁止的单词的XMPP消息.)
C: <message from='[email protected]/foo' to='[email protected]' id='vq71f4nb'> <body>%#&@^!!!</body> </message> S: <message from='[email protected]' id='vq71f4nb' to='[email protected]/foo'> <error by='example.net' type='modify'> <policy-violation xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </message>
预期的接收者暂时不可用, 正在维护, 等等; 相关的错误类型应该是"wait".
C: <presence from='[email protected]/balcony' id='y2bs71v4' to='[email protected]/JulieC'> <x xmlns='http://jabber.org/protocol/muc'/> </presence> E: <presence from='[email protected]/JulieC' id='y2bs71v4' to='[email protected]/balcony'> <error type='wait'> <recipient-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </presence>
接收者或服务器重定向该信息的请求到另一个实体, 典型的临时发生的情形(和<gone/>错误条件相反, 它用于永久性的地址错误); 相关的错误类型应该是"modify",并且该错误节应该在<redirect/>元素的XML字符串数据中包含替代的地址(它必须是一个发送者可以与之通讯的URI或IRI, 通常是一个XMPP‑URI定义的XMPP IRI).
C: <presence from='[email protected]/balcony' id='y2bs71v4' to='[email protected]/JulieC'> <x xmlns='http://jabber.org/protocol/muc'/> </presence> E: <presence from='[email protected]/JulieC' id='y2bs71v4' to='[email protected]/balcony' type='error'> <error type='modify'> <redirect xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'> xmpp:[email protected] </redirect> </error> </presence>
请求的实体没有被授权访问请求的服务,因为需要事先注册(提前注册的例子包括XMPP多用户聊天XEP-0045中仅限会员的房间和到非XMPP即时消息服务的网关, 传统上使用网关XEP‑0100是需要注册的); 相关的错误类型应该是"auth".
C: <presence from='[email protected]/balcony' id='y2bs71v4' to='[email protected]/JulieC'> <x xmlns='http://jabber.org/protocol/muc'/> </presence> E: <presence from='[email protected]/JulieC' id='y2bs71v4' to='[email protected]/balcony'> <error type='auth'> <registration-required xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </presence>
一个远程服务器或预期的接收者的JID的一部分所代表的服务不存在或不能解析(例如, 没有 _xmpp-server._tcp DNS SRV记录, A记录或AAAA记录解析也失败了, 或A/AAAA查询成功了但是在IANA注册了的端口5269上没有应答); 相关错误类型应该是"cancel".
C: <message from='[email protected]/home' id='ud7n1f4h' to='[email protected]' type='chat'> <body>yt?</body> </message> E: <message from='[email protected]' id='ud7n1f4h' to='[email protected]/home' type='error'> <error type='cancel'> <remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </message>
远程服务器或作为预定的接收者的全JID的一部分(或履行请求所需要的)的服务能被解析但是无法在合理的时间内与之建立通讯(例如, 无法在解析到的IP地址和端口上建立一个XML流, 或可以建立一个XML流但是因为TLS, SASL, Server Dialback的问题导致流协商失败, 等等); 相关的错误类型应该是"wait" (除非该错误是更永久性的, 例如, 远程服务器能被找到但是无法被认证或它违反了安全策略).
C: <message from='[email protected]/home' id='ud7n1f4h' to='[email protected]' type='chat'> <body>yt?</body> </message> E: <message from='[email protected]' id='ud7n1f4h' to='[email protected]/home' type='error'> <error type='wait'> <remote-server-timeout xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </message>
服务器或接收者忙或缺乏必要的系统资源来服务该请求; 相关的错误类型应该是"wait".
C: <iq from='[email protected]/foo' id='kj4vz31m' to='pubsub.example.com' type='get'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <items node='my_musings'/> </pubsub> </iq> E: <iq from='pubsub.example.com' id='kj4vz31m' to='[email protected]/foo' type='error'> <error type='wait'> <resource-constraint xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </iq>
服务器或接收者当前未提供被请求的服务; 相关的错误类型应该是"cancel".
C: <message from='[email protected]/foo' to='[email protected]'> <body>Hello?</body> </message> S: <message from='[email protected]/foo' to='[email protected]'> <error type='cancel'> <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </message>
提出请求的实体没有被授权访问所请求的服务,因为需要事先订阅(事先订阅的例子包括授权接收XMPP‑IM定义的联机状态信息和用于XEP‑0060定义的XMPP发布-订阅的 opt-in 数据种子); 相关的错误类型应该是"auth".
C: <message from='[email protected]/orchard' id='pa73b4n7' to='[email protected]' type='chat'> <subject>ACT II, SCENE II</subject> <body>help, I forgot my lines!</body> </message> E: <message from='[email protected]' id='pa73b4n7' to='[email protected]/orchard' type='error'> <error type='auth'> <subscription-required xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </message>
该错误条件不在本列表中的其他错误条件之中; 任何错误类型都可能和本条件有关, 并且除非和应用特有的条件联合在一起,它应该不被使用.
C: <message from='[email protected]' id='richard2-4.1.247' to='[email protected]'> <body>My lord, dispatch; read o'er these articles.</body> <amp xmlns='http://jabber.org/protocol/amp'> <rule action='notify' condition='deliver' value='stored'/> </amp> </message> S: <message from='example.org' id='amp1' to='[email protected]/field' type='error'> <amp xmlns='http://jabber.org/protocol/amp' from='[email protected]' status='error' to='[email protected]/field'> <rule action='error' condition='deliver' value='stored'/> </amp> <error type='modify'> <undefined-condition xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> <failed-rules xmlns='http://jabber.org/protocol/amp#errors'> <rule action='error' condition='deliver' value='stored'/> </failed-rules> </error> </message>
接收者或服务器理解这个请求但是不希望它在这个时候出现(即, 该请求顺序错了); 相关的错误类型应该是"wait"或"modify".
C: <iq from='[email protected]/foo' id='o6hsv25z' to='pubsub.example.com' type='set'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <unsubscribe node='my_musings' jid='[email protected]'/> </pubsub> </iq> E: <iq from='pubsub.example.com' id='o6hsv25z' to='[email protected]/foo' type='error'> <error type='modify'> <unexpected-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> <not-subscribed xmlns='http://jabber.org/protocol/pubsub#errors'/> </error> </iq>
大家知道, 一个应用可以提供应用特有的节错误信息,通过在错误元素中包含一个正确的命名空间的子元素. 典型的, 该应用特有的元素补充或进一步限定一个已定义的元素. 从而, 该<error/>元素将包含两个或三个子元素.
<iq id='ixc3v1b9' type='error'> <error type='modify'> <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> <too-many-parameters xmlns='http://example.org/ns'/> </error> </iq> <message type='error' id='7h3baci9'> <error type='modify'> <undefined-condition xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> <text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'> [ ... application-specific information ... ] </text> <too-many-parameters xmlns='http://example.org/ns'/> </error> </message>
一个接收到它不理解的应用特有的错误条件的实体必须忽略那个条件但适当处理该错误节的其他部分.