1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2025-09-09 17:19:39 +02:00

[core] Wrap current connection exception when re-throwing

Instead of directly throwing the current connection exception, wrap
it, so we do not lose the stack trace of the thread invoking
waitForConditionorThrowConnectionException().
This commit is contained in:
Florian Schmaus 2024-10-17 17:34:05 +02:00
parent 3c5fb5810e
commit 9e5ac5a39a
5 changed files with 24 additions and 39 deletions

View file

@ -281,8 +281,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
*/
protected Writer writer;
protected SmackException currentSmackException;
protected XMPPException currentXmppException;
private Exception currentConnectionException;
protected boolean tlsHandled;
@ -511,8 +510,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
public abstract boolean isUsingCompression();
protected void initState() {
currentSmackException = null;
currentXmppException = null;
currentConnectionException = null;
saslFeatureReceived = lastFeaturesReceived = tlsHandled = false;
// TODO: We do not init closingStreamReceived here, as the integration tests use it to check if we waited for
// it.
@ -686,28 +684,12 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
return streamId;
}
protected final void throwCurrentConnectionException() throws SmackException, XMPPException {
if (currentSmackException != null) {
throw currentSmackException;
} else if (currentXmppException != null) {
throw currentXmppException;
}
throw new AssertionError("No current connection exception set, although throwCurrentException() was called");
}
protected final boolean hasCurrentConnectionException() {
return currentSmackException != null || currentXmppException != null;
return currentConnectionException != null;
}
protected final void setCurrentConnectionExceptionAndNotify(Exception exception) {
if (exception instanceof SmackException) {
currentSmackException = (SmackException) exception;
} else if (exception instanceof XMPPException) {
currentXmppException = (XMPPException) exception;
} else {
currentSmackException = new SmackException.SmackWrappedException(exception);
}
currentConnectionException = exception;
notifyWaitingThreads();
}
@ -741,10 +723,12 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
return true;
}
protected final void waitForConditionOrThrowConnectionException(Supplier<Boolean> condition, String waitFor) throws InterruptedException, SmackException, XMPPException {
protected final void waitForConditionOrThrowConnectionException(Supplier<Boolean> condition, String waitFor)
throws InterruptedException, SmackException.SmackWrappedException, NoResponseException {
boolean success = waitFor(() -> condition.get().booleanValue() || hasCurrentConnectionException());
if (hasCurrentConnectionException()) {
throwCurrentConnectionException();
final Exception currentConnectionException = this.currentConnectionException;
if (currentConnectionException != null) {
throw new SmackException.SmackWrappedException(currentConnectionException);
}
// If there was no connection exception and we still did not successfully wait for the condition to hold, then
@ -1048,7 +1032,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
protected final boolean waitForClosingStreamTagFromServer() {
try {
waitForConditionOrThrowConnectionException(() -> closingStreamReceived, "closing stream tag from the server");
} catch (InterruptedException | SmackException | XMPPException e) {
} catch (InterruptedException | SmackException.SmackWrappedException | NoResponseException e) {
LOGGER.log(Level.INFO, "Exception while waiting for closing stream element from the server " + this, e);
return false;
}

View file

@ -39,6 +39,7 @@ import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.OutgoingQueueFullException;
import org.jivesoftware.smack.SmackException.SmackWrappedException;
import org.jivesoftware.smack.SmackFuture;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.XMPPException.FailedNonzaException;
@ -259,7 +260,7 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne
@Override
public void waitForConditionOrThrowConnectionException(Supplier<Boolean> condition, String waitFor)
throws InterruptedException, SmackException, XMPPException {
throws InterruptedException, SmackWrappedException, NoResponseException {
ModularXmppClientToServerConnection.this.waitForConditionOrThrowConnectionException(condition, waitFor);
}
@ -596,8 +597,7 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne
case "error":
StreamError streamError = PacketParserUtils.parseStreamError(parser, null);
StreamErrorException streamErrorException = new StreamErrorException(streamError);
currentXmppException = streamErrorException;
notifyWaitingThreads();
setCurrentConnectionExceptionAndNotify(streamErrorException);
throw streamErrorException;
case "features":
parseFeatures(parser);
@ -1048,8 +1048,7 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne
XmppInputOutputFilter filter = it.next();
try {
filter.waitUntilInputOutputClosed();
} catch (IOException | CertificateException | InterruptedException | SmackException
| XMPPException e) {
} catch (IOException | CertificateException | InterruptedException | SmackException | XMPPException e) {
LOGGER.log(Level.WARNING, "waitUntilInputOutputClosed() threw", e);
}
}

View file

@ -26,6 +26,7 @@ import java.util.Queue;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.SmackWrappedException;
import org.jivesoftware.smack.SmackReactor;
import org.jivesoftware.smack.SmackReactor.ChannelSelectedCallback;
import org.jivesoftware.smack.XMPPException;
@ -127,7 +128,8 @@ public abstract class ModularXmppClientToServerConnectionInternal {
public abstract void asyncGo(Runnable runnable);
public abstract void waitForConditionOrThrowConnectionException(Supplier<Boolean> condition, String waitFor) throws InterruptedException, SmackException, XMPPException;
public abstract void waitForConditionOrThrowConnectionException(Supplier<Boolean> condition, String waitFor)
throws InterruptedException, SmackWrappedException, NoResponseException;
public abstract void notifyWaitingThreads();