diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java index 52caca13b..b1b8fb208 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -763,8 +763,11 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { @Override public StanzaCollector createStanzaCollectorAndSend(StanzaFilter packetFilter, Stanza packet) throws NotConnectedException, InterruptedException { + StanzaCollector.Configuration configuration = StanzaCollector.newConfiguration() + .setStanzaFilter(packetFilter) + .setRequest(packet); // Create the packet collector before sending the packet - StanzaCollector packetCollector = createStanzaCollector(packetFilter); + StanzaCollector packetCollector = createStanzaCollector(configuration); try { // Now we can send the packet as the collector has been created sendStanza(packet); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/StanzaCollector.java b/smack-core/src/main/java/org/jivesoftware/smack/StanzaCollector.java index 46a83530e..4a7c284eb 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/StanzaCollector.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/StanzaCollector.java @@ -53,6 +53,8 @@ public class StanzaCollector { private final XMPPConnection connection; + private final Stanza request; + private boolean cancelled = false; /** @@ -67,6 +69,7 @@ public class StanzaCollector { this.packetFilter = configuration.packetFilter; this.resultQueue = new ArrayBlockingQueue<>(configuration.size); this.collectorToReset = configuration.collectorToReset; + this.request = configuration.request; } /** @@ -314,6 +317,7 @@ public class StanzaCollector { private StanzaFilter packetFilter; private int size = SmackConfiguration.getStanzaCollectorSize(); private StanzaCollector collectorToReset; + private Stanza request; private Configuration() { } @@ -366,5 +370,10 @@ public class StanzaCollector { this.collectorToReset = collector; return this; } + + public Configuration setRequest(Stanza request) { + this.request = request; + return this; + } } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/XMPPException.java b/smack-core/src/main/java/org/jivesoftware/smack/XMPPException.java index 2fe2386a6..e9eb4d05b 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/XMPPException.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/XMPPException.java @@ -77,6 +77,11 @@ public abstract class XMPPException extends Exception { private final StanzaError error; private final Stanza stanza; + /** + * The request which resulted in the XMPP protocol error response. May be {@code null}. + */ + private final Stanza request; + /** * Creates a new XMPPErrorException with the given builder. * @@ -95,9 +100,22 @@ public abstract class XMPPException extends Exception { * @param error the root cause of the exception. */ public XMPPErrorException(Stanza stanza, StanzaError error) { + this(stanza, error, null); + } + + /** + * Creates a new XMPPErrorException with the XMPPError that was the root case of the exception. + * + * @param request the request which triggered the error. + * @param stanza stanza that contained the exception. + * @param error the root cause of the exception. + * @since 4.3.0 + */ + public XMPPErrorException(Stanza stanza, StanzaError error, Stanza request) { super(); this.error = error; this.stanza = stanza; + this.request = request; } /** @@ -110,6 +128,16 @@ public abstract class XMPPException extends Exception { return error; } + /** + * Get the request which triggered the error response causing this exception. + * + * @return the request or {@code null}. + * @since 4.3.0 + */ + public Stanza getRequest() { + return request; + } + @Override public String getMessage() { StringBuilder sb = new StringBuilder(); @@ -123,13 +151,22 @@ public abstract class XMPPException extends Exception { sb.append(error); + if (request != null) { + sb.append(" as result of the following request: "); + sb.append(request); + } + return sb.toString(); } public static void ifHasErrorThenThrow(Stanza packet) throws XMPPErrorException { + ifHasErrorThenThrow(packet, null); + } + + public static void ifHasErrorThenThrow(Stanza packet, Stanza request) throws XMPPErrorException { StanzaError xmppError = packet.getError(); if (xmppError != null) { - throw new XMPPErrorException(packet, xmppError); + throw new XMPPErrorException(packet, xmppError, request); } } }