mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-25 21:42:07 +01: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:
parent
3c5fb5810e
commit
9e5ac5a39a
5 changed files with 24 additions and 39 deletions
|
@ -281,8 +281,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
*/
|
*/
|
||||||
protected Writer writer;
|
protected Writer writer;
|
||||||
|
|
||||||
protected SmackException currentSmackException;
|
private Exception currentConnectionException;
|
||||||
protected XMPPException currentXmppException;
|
|
||||||
|
|
||||||
protected boolean tlsHandled;
|
protected boolean tlsHandled;
|
||||||
|
|
||||||
|
@ -511,8 +510,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
public abstract boolean isUsingCompression();
|
public abstract boolean isUsingCompression();
|
||||||
|
|
||||||
protected void initState() {
|
protected void initState() {
|
||||||
currentSmackException = null;
|
currentConnectionException = null;
|
||||||
currentXmppException = null;
|
|
||||||
saslFeatureReceived = lastFeaturesReceived = tlsHandled = false;
|
saslFeatureReceived = lastFeaturesReceived = tlsHandled = false;
|
||||||
// TODO: We do not init closingStreamReceived here, as the integration tests use it to check if we waited for
|
// TODO: We do not init closingStreamReceived here, as the integration tests use it to check if we waited for
|
||||||
// it.
|
// it.
|
||||||
|
@ -686,28 +684,12 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
return streamId;
|
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() {
|
protected final boolean hasCurrentConnectionException() {
|
||||||
return currentSmackException != null || currentXmppException != null;
|
return currentConnectionException != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void setCurrentConnectionExceptionAndNotify(Exception exception) {
|
protected final void setCurrentConnectionExceptionAndNotify(Exception exception) {
|
||||||
if (exception instanceof SmackException) {
|
currentConnectionException = exception;
|
||||||
currentSmackException = (SmackException) exception;
|
|
||||||
} else if (exception instanceof XMPPException) {
|
|
||||||
currentXmppException = (XMPPException) exception;
|
|
||||||
} else {
|
|
||||||
currentSmackException = new SmackException.SmackWrappedException(exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyWaitingThreads();
|
notifyWaitingThreads();
|
||||||
}
|
}
|
||||||
|
@ -741,10 +723,12 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
return true;
|
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());
|
boolean success = waitFor(() -> condition.get().booleanValue() || hasCurrentConnectionException());
|
||||||
if (hasCurrentConnectionException()) {
|
final Exception currentConnectionException = this.currentConnectionException;
|
||||||
throwCurrentConnectionException();
|
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
|
// 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() {
|
protected final boolean waitForClosingStreamTagFromServer() {
|
||||||
try {
|
try {
|
||||||
waitForConditionOrThrowConnectionException(() -> closingStreamReceived, "closing stream tag from the server");
|
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);
|
LOGGER.log(Level.INFO, "Exception while waiting for closing stream element from the server " + this, e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||||
import org.jivesoftware.smack.SmackException.OutgoingQueueFullException;
|
import org.jivesoftware.smack.SmackException.OutgoingQueueFullException;
|
||||||
|
import org.jivesoftware.smack.SmackException.SmackWrappedException;
|
||||||
import org.jivesoftware.smack.SmackFuture;
|
import org.jivesoftware.smack.SmackFuture;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.XMPPException.FailedNonzaException;
|
import org.jivesoftware.smack.XMPPException.FailedNonzaException;
|
||||||
|
@ -259,7 +260,7 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void waitForConditionOrThrowConnectionException(Supplier<Boolean> condition, String waitFor)
|
public void waitForConditionOrThrowConnectionException(Supplier<Boolean> condition, String waitFor)
|
||||||
throws InterruptedException, SmackException, XMPPException {
|
throws InterruptedException, SmackWrappedException, NoResponseException {
|
||||||
ModularXmppClientToServerConnection.this.waitForConditionOrThrowConnectionException(condition, waitFor);
|
ModularXmppClientToServerConnection.this.waitForConditionOrThrowConnectionException(condition, waitFor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,8 +597,7 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne
|
||||||
case "error":
|
case "error":
|
||||||
StreamError streamError = PacketParserUtils.parseStreamError(parser, null);
|
StreamError streamError = PacketParserUtils.parseStreamError(parser, null);
|
||||||
StreamErrorException streamErrorException = new StreamErrorException(streamError);
|
StreamErrorException streamErrorException = new StreamErrorException(streamError);
|
||||||
currentXmppException = streamErrorException;
|
setCurrentConnectionExceptionAndNotify(streamErrorException);
|
||||||
notifyWaitingThreads();
|
|
||||||
throw streamErrorException;
|
throw streamErrorException;
|
||||||
case "features":
|
case "features":
|
||||||
parseFeatures(parser);
|
parseFeatures(parser);
|
||||||
|
@ -1048,8 +1048,7 @@ public final class ModularXmppClientToServerConnection extends AbstractXMPPConne
|
||||||
XmppInputOutputFilter filter = it.next();
|
XmppInputOutputFilter filter = it.next();
|
||||||
try {
|
try {
|
||||||
filter.waitUntilInputOutputClosed();
|
filter.waitUntilInputOutputClosed();
|
||||||
} catch (IOException | CertificateException | InterruptedException | SmackException
|
} catch (IOException | CertificateException | InterruptedException | SmackException | XMPPException e) {
|
||||||
| XMPPException e) {
|
|
||||||
LOGGER.log(Level.WARNING, "waitUntilInputOutputClosed() threw", e);
|
LOGGER.log(Level.WARNING, "waitUntilInputOutputClosed() threw", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Queue;
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||||
|
import org.jivesoftware.smack.SmackException.SmackWrappedException;
|
||||||
import org.jivesoftware.smack.SmackReactor;
|
import org.jivesoftware.smack.SmackReactor;
|
||||||
import org.jivesoftware.smack.SmackReactor.ChannelSelectedCallback;
|
import org.jivesoftware.smack.SmackReactor.ChannelSelectedCallback;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
@ -127,7 +128,8 @@ public abstract class ModularXmppClientToServerConnectionInternal {
|
||||||
|
|
||||||
public abstract void asyncGo(Runnable runnable);
|
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();
|
public abstract void notifyWaitingThreads();
|
||||||
|
|
||||||
|
|
|
@ -889,8 +889,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
if (startTlsFeature != null) {
|
if (startTlsFeature != null) {
|
||||||
if (startTlsFeature.required() && config.getSecurityMode() == SecurityMode.disabled) {
|
if (startTlsFeature.required() && config.getSecurityMode() == SecurityMode.disabled) {
|
||||||
SecurityRequiredByServerException smackException = new SecurityRequiredByServerException();
|
SecurityRequiredByServerException smackException = new SecurityRequiredByServerException();
|
||||||
currentSmackException = smackException;
|
setCurrentConnectionExceptionAndNotify(smackException);
|
||||||
notifyWaitingThreads();
|
|
||||||
throw smackException;
|
throw smackException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1020,8 +1019,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
// situation. It is still possible to authenticate and
|
// situation. It is still possible to authenticate and
|
||||||
// use the connection but using an uncompressed connection
|
// use the connection but using an uncompressed connection
|
||||||
// TODO Parse failure stanza
|
// TODO Parse failure stanza
|
||||||
currentSmackException = new SmackException.SmackMessageException("Could not establish compression");
|
SmackException.SmackMessageException exception = new SmackException.SmackMessageException("Could not establish compression");
|
||||||
notifyWaitingThreads();
|
setCurrentConnectionExceptionAndNotify(exception);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
parseAndProcessNonza(parser);
|
parseAndProcessNonza(parser);
|
||||||
|
|
|
@ -46,9 +46,11 @@ import javax.net.ssl.SSLSession;
|
||||||
|
|
||||||
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
|
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
|
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||||
import org.jivesoftware.smack.SmackException.SecurityRequiredByClientException;
|
import org.jivesoftware.smack.SmackException.SecurityRequiredByClientException;
|
||||||
import org.jivesoftware.smack.SmackException.SecurityRequiredByServerException;
|
import org.jivesoftware.smack.SmackException.SecurityRequiredByServerException;
|
||||||
import org.jivesoftware.smack.SmackException.SmackCertificateException;
|
import org.jivesoftware.smack.SmackException.SmackCertificateException;
|
||||||
|
import org.jivesoftware.smack.SmackException.SmackWrappedException;
|
||||||
import org.jivesoftware.smack.SmackFuture;
|
import org.jivesoftware.smack.SmackFuture;
|
||||||
import org.jivesoftware.smack.SmackFuture.InternalSmackFuture;
|
import org.jivesoftware.smack.SmackFuture.InternalSmackFuture;
|
||||||
import org.jivesoftware.smack.SmackReactor.SelectionKeyAttachment;
|
import org.jivesoftware.smack.SmackReactor.SelectionKeyAttachment;
|
||||||
|
@ -1201,7 +1203,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM
|
||||||
return handshakeStatus == TlsHandshakeStatus.successful || handshakeStatus == TlsHandshakeStatus.failed;
|
return handshakeStatus == TlsHandshakeStatus.successful || handshakeStatus == TlsHandshakeStatus.failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void waitForHandshakeFinished() throws InterruptedException, CertificateException, SSLException, SmackException, XMPPException {
|
private void waitForHandshakeFinished() throws InterruptedException, CertificateException, SSLException, SmackWrappedException, NoResponseException {
|
||||||
connectionInternal.waitForConditionOrThrowConnectionException(() -> isHandshakeFinished(), "TLS handshake to finish");
|
connectionInternal.waitForConditionOrThrowConnectionException(() -> isHandshakeFinished(), "TLS handshake to finish");
|
||||||
|
|
||||||
if (handshakeStatus == TlsHandshakeStatus.failed) {
|
if (handshakeStatus == TlsHandshakeStatus.failed) {
|
||||||
|
@ -1234,8 +1236,7 @@ public class XmppTcpTransportModule extends ModularXmppClientToServerConnectionM
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void waitUntilInputOutputClosed() throws IOException, CertificateException, InterruptedException,
|
public void waitUntilInputOutputClosed() throws IOException, CertificateException, InterruptedException, SmackWrappedException, NoResponseException {
|
||||||
SmackException, XMPPException {
|
|
||||||
waitForHandshakeFinished();
|
waitForHandshakeFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue