XMPPException.java

  1. /**
  2.  *
  3.  * Copyright 2003-2007 Jive Software.
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.jivesoftware.smack;

  18. import org.jivesoftware.smack.packet.Nonza;
  19. import org.jivesoftware.smack.packet.Stanza;
  20. import org.jivesoftware.smack.packet.StanzaError;
  21. import org.jivesoftware.smack.packet.StreamError;

  22. import org.jxmpp.jid.Jid;

  23. /**
  24.  * A generic exception that is thrown when an error occurs performing an
  25.  * XMPP operation. XMPP servers can respond to error conditions with an error code
  26.  * and textual description of the problem, which are encapsulated in the XMPPError
  27.  * class. When appropriate, an XMPPError instance is attached instances of this exception.<p>
  28.  *
  29.  * When a stream error occurred, the server will send a stream error to the client before
  30.  * closing the connection. Stream errors are unrecoverable errors. When a stream error
  31.  * is sent to the client an XMPPException will be thrown containing the StreamError sent
  32.  * by the server.
  33.  *
  34.  * @see StanzaError
  35.  * @author Matt Tucker
  36.  */
  37. public abstract class XMPPException extends Exception {
  38.     private static final long serialVersionUID = 6881651633890968625L;


  39.     /**
  40.      * Creates a new XMPPException.
  41.      */
  42.     protected XMPPException() {
  43.         super();
  44.     }

  45.     /**
  46.      * Creates a new XMPPException with a description of the exception.
  47.      *
  48.      * @param message description of the exception.
  49.      */
  50.     protected XMPPException(String message) {
  51.         super(message);
  52.     }

  53.     /**
  54.      * Creates a new XMPPException with a description of the exception and the
  55.      * Throwable that was the root cause of the exception.
  56.      *
  57.      * @param message a description of the exception.
  58.      * @param wrappedThrowable the root cause of the exception.
  59.      */
  60.     protected XMPPException(String message, Throwable wrappedThrowable) {
  61.         super(message, wrappedThrowable);
  62.     }

  63.     /**
  64.      * An exception caused by an XMPP error stanza response on the protocol level. You can examine the underlying
  65.      * {@link StanzaError} by calling {@link #getStanzaError()}.
  66.      */
  67.     public static class XMPPErrorException extends XMPPException {
  68.         /**
  69.          *
  70.          */
  71.         private static final long serialVersionUID = 212790389529249604L;
  72.         private final StanzaError error;
  73.         private final Stanza stanza;

  74.         /**
  75.          * The request which resulted in the XMPP protocol error response. May be {@code null}.
  76.          */
  77.         private final Stanza request;

  78.         /**
  79.          * Creates a new XMPPErrorException with the XMPPError that was the root case of the exception.
  80.          *
  81.          * @param stanza stanza that contained the exception.
  82.          * @param error the root cause of the exception.
  83.          */
  84.         public XMPPErrorException(Stanza stanza, StanzaError error) {
  85.             this(stanza, error, null);
  86.         }

  87.         /**
  88.          * Creates a new XMPPErrorException with the XMPPError that was the root case of the exception.
  89.          *
  90.          * @param request the request which triggered the error.
  91.          * @param stanza stanza that contained the exception.
  92.          * @param error the root cause of the exception.
  93.          * @since 4.3.0
  94.          */
  95.         public XMPPErrorException(Stanza stanza, StanzaError error, Stanza request) {
  96.             super();
  97.             this.error = error;
  98.             this.stanza = stanza;
  99.             this.request = request;
  100.         }

  101.         /**
  102.          * Returns the stanza error extension element associated with this exception.
  103.          *
  104.          * @return the stanza error extension element associated with this exception.
  105.          */
  106.         public StanzaError getStanzaError() {
  107.             return error;
  108.         }

  109.         /**
  110.          * Gets the stanza associated with this exception.
  111.          *
  112.          * @return the stanza from which this exception was created or {@code null} if the exception is not from a
  113.          * stanza.
  114.          */
  115.         public Stanza getStanza() {
  116.             return stanza;
  117.         }

  118.         /**
  119.          * Get the request which triggered the error response causing this exception.
  120.          *
  121.          * @return the request or {@code null}.
  122.          * @since 4.3.0
  123.          */
  124.         public Stanza getRequest() {
  125.             return request;
  126.         }

  127.         @Override
  128.         public String getMessage() {
  129.             StringBuilder sb = new StringBuilder();

  130.             if (stanza != null) {
  131.                 Jid from = stanza.getFrom();
  132.                 if (from != null) {
  133.                     sb.append("XMPP error reply received from " + from + ": ");
  134.                 }
  135.             }

  136.             sb.append(error);

  137.             if (request != null) {
  138.                 sb.append(" as result of the following request: ");
  139.                 sb.append(request);
  140.             }

  141.             return sb.toString();
  142.         }

  143.         public static void ifHasErrorThenThrow(Stanza packet) throws XMPPErrorException {
  144.             ifHasErrorThenThrow(packet, null);
  145.         }

  146.         public static void ifHasErrorThenThrow(Stanza packet, Stanza request) throws XMPPErrorException {
  147.             StanzaError xmppError = packet.getError();
  148.             if (xmppError != null) {
  149.                 throw new XMPPErrorException(packet, xmppError, request);
  150.             }
  151.         }
  152.     }

  153.     public static class FailedNonzaException extends XMPPException {

  154.         /**
  155.          *
  156.          */
  157.         private static final long serialVersionUID = 1L;

  158.         private final StanzaError.Condition condition;

  159.         private final Nonza nonza;

  160.         public FailedNonzaException(Nonza failedNonza) {
  161.             this(failedNonza, null);
  162.         }

  163.         public FailedNonzaException(Nonza nonza, StanzaError.Condition condition) {
  164.             this.condition = condition;
  165.             this.nonza = nonza;
  166.         }

  167.         public StanzaError.Condition getCondition() {
  168.             return condition;
  169.         }

  170.         public Nonza getNonza() {
  171.             return nonza;
  172.         }
  173.     }

  174.     public static class StreamErrorException extends XMPPException {
  175.         /**
  176.          *
  177.          */
  178.         private static final long serialVersionUID = 3400556867134848886L;
  179.         private final StreamError streamError;

  180.         /**
  181.          * Creates a new XMPPException with the stream error that was the root case of the
  182.          * exception. When a stream error is received from the server then the underlying connection
  183.          * will be closed by the server.
  184.          *
  185.          * @param streamError the root cause of the exception.
  186.          */
  187.         public StreamErrorException(StreamError streamError) {
  188.             super(streamError.getCondition().toString()
  189.                   + " You can read more about the meaning of this stream error at http://xmpp.org/rfcs/rfc6120.html#streams-error-conditions\n"
  190.                   + streamError.toString());
  191.             this.streamError = streamError;
  192.         }

  193.         /**
  194.          * Returns the StreamError associated with this exception. The underlying TCP connection is
  195.          * closed by the server after sending the stream error to the client.
  196.          *
  197.          * @return the StreamError associated with this exception.
  198.          */
  199.         public StreamError getStreamError() {
  200.             return streamError;
  201.         }

  202.     }
  203. }