diff --git a/source/org/jivesoftware/smack/PacketReader.java b/source/org/jivesoftware/smack/PacketReader.java index bab35ff11..a9004e284 100644 --- a/source/org/jivesoftware/smack/PacketReader.java +++ b/source/org/jivesoftware/smack/PacketReader.java @@ -30,6 +30,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.util.*; +import java.io.IOException; /** * Listens for XML traffic from the XMPP server and parses it into packet objects. @@ -305,6 +306,9 @@ class PacketReader { } } } + else if (parser.getName().equals("error")) { + throw new XMPPException(parseStreamError(parser)); + } else if (parser.getName().equals("features")) { parseFeatures(parser); } @@ -409,6 +413,25 @@ class PacketReader { } } + private StreamError parseStreamError(XmlPullParser parser) throws IOException, + XmlPullParserException { + StreamError streamError = null; + boolean done = false; + while (!done) { + int eventType = parser.next(); + + if (eventType == XmlPullParser.START_TAG) { + streamError = new StreamError(parser.getName()); + } + else if (eventType == XmlPullParser.END_TAG) { + if (parser.getName().equals("error")) { + done = true; + } + } + } + return streamError; + } + private void parseFeatures(XmlPullParser parser) throws Exception { boolean startTLSReceived = false; boolean done = false; diff --git a/source/org/jivesoftware/smack/XMPPException.java b/source/org/jivesoftware/smack/XMPPException.java index 913ccf888..5b60220ba 100644 --- a/source/org/jivesoftware/smack/XMPPException.java +++ b/source/org/jivesoftware/smack/XMPPException.java @@ -21,6 +21,7 @@ package org.jivesoftware.smack; import org.jivesoftware.smack.packet.XMPPError; +import org.jivesoftware.smack.packet.StreamError; import java.io.PrintStream; import java.io.PrintWriter; @@ -29,13 +30,19 @@ import java.io.PrintWriter; * A generic exception that is thrown when an error occurs performing an * XMPP operation. XMPP servers can respond to error conditions with an error code * and textual description of the problem, which are encapsulated in the XMPPError - * class. When appropriate, an XMPPError instance is attached instances of this exception. + * class. When appropriate, an XMPPError instance is attached instances of this exception.

+ * + * When a stream error occured, the server will send a stream error to the client before + * closing the connection. Stream errors are unrecoverable errors. When a stream error + * is sent to the client an XMPPException will be thrown containing the StreamError sent + * by the server. * * @see XMPPError * @author Matt Tucker */ public class XMPPException extends Exception { + private StreamError streamError = null; private XMPPError error = null; private Throwable wrappedThrowable = null; @@ -66,6 +73,18 @@ public class XMPPException extends Exception { this.wrappedThrowable = wrappedThrowable; } + /** + * Cretaes a new XMPPException with the stream error that was the root case of the + * exception. When a stream error is received from the server then the underlying + * TCP connection will be closed by the server. + * + * @param streamError the root cause of the exception. + */ + public XMPPException(StreamError streamError) { + super(); + this.streamError = streamError; + } + /** * Cretaes a new XMPPException with the XMPPError that was the root case of the * exception. @@ -125,6 +144,17 @@ public class XMPPException extends Exception { return error; } + /** + * Returns the StreamError asscociated with this exception, or null if there + * isn't one. The underlying TCP connection is closed by the server after sending the + * stream error to the client. + * + * @return the StreamError asscociated with this exception. + */ + public StreamError getStreamError() { + return streamError; + } + /** * Returns the Throwable asscociated with this exception, or null if there * isn't one. @@ -162,6 +192,9 @@ public class XMPPException extends Exception { if (msg == null && error != null) { return error.toString(); } + else if (msg == null && streamError != null) { + return streamError.toString(); + } return msg; } @@ -174,6 +207,9 @@ public class XMPPException extends Exception { if (error != null) { buf.append(error); } + if (streamError != null) { + buf.append(streamError); + } if (wrappedThrowable != null) { buf.append("\n -- caused by: ").append(wrappedThrowable); }