Search in sources :

Example 1 with UnrecognizedCertificateException

use of org.matrix.androidsdk.ssl.UnrecognizedCertificateException in project matrix-android-sdk by matrix-org.

the class UnsentEventsManager method onEventSendingFailed.

/**
 * warns that an event failed to be sent.
 *
 * @param eventDescription             the event description
 * @param ignoreEventTimeLifeInOffline tell if the event timelife is ignored in offline mode
 * @param retrofitError                the retrofit error .
 * @param apiCallback                  the apiCallback.
 * @param requestRetryCallBack         requestRetryCallBack.
 */
public void onEventSendingFailed(final String eventDescription, final boolean ignoreEventTimeLifeInOffline, final RetrofitError retrofitError, final ApiCallback apiCallback, final RestAdapterCallback.RequestRetryCallBack requestRetryCallBack) {
    boolean isManaged = false;
    if (null != eventDescription) {
        Log.d(LOG_TAG, "Fail to send [" + eventDescription + "]");
    }
    if ((null != requestRetryCallBack) && (null != apiCallback)) {
        synchronized (mUnsentEventsMap) {
            UnsentEventSnapshot snapshot;
            // Try to convert this into a Matrix error
            MatrixError mxError = null;
            if (null != retrofitError) {
                try {
                    mxError = (MatrixError) retrofitError.getBodyAs(MatrixError.class);
                } catch (Exception e) {
                    mxError = null;
                }
            }
            // trace the matrix error.
            if ((null != eventDescription) && (null != mxError)) {
                Log.d(LOG_TAG, "Matrix error " + mxError.errcode + " " + mxError.getMessage() + " [" + eventDescription + "]");
                if (MatrixError.isConfigurationErrorCode(mxError.errcode)) {
                    Log.e(LOG_TAG, "## onEventSendingFailed() : invalid token detected");
                    mDataHandler.onConfigurationError(mxError.errcode);
                    triggerErrorCallback(mDataHandler, eventDescription, retrofitError, apiCallback);
                    return;
                }
            }
            int matrixRetryTimeout = -1;
            if ((null != mxError) && MatrixError.LIMIT_EXCEEDED.equals(mxError.errcode) && (null != mxError.retry_after_ms)) {
                matrixRetryTimeout = mxError.retry_after_ms + 200;
            }
            if ((null != retrofitError) && retrofitError.isNetworkError()) {
                UnrecognizedCertificateException unrecCertEx = CertUtil.getCertificateException(retrofitError);
                if (null != unrecCertEx) {
                    Log.e(LOG_TAG, "## onEventSendingFailed() : SSL issue detected");
                    mDataHandler.onSSLCertificateError(unrecCertEx);
                    triggerErrorCallback(mDataHandler, eventDescription, retrofitError, apiCallback);
                    return;
                }
            }
            // some matrix errors are not trapped.
            if ((null == mxError) || !mxError.isSupportedErrorCode() || MatrixError.LIMIT_EXCEEDED.equals(mxError.errcode)) {
                // is it the first time that the event has been sent ?
                if (mUnsentEventsMap.containsKey(apiCallback)) {
                    snapshot = mUnsentEventsMap.get(apiCallback);
                    snapshot.mIsResending = false;
                    snapshot.stopTimer();
                    // assume that LIMIT_EXCEEDED error is not a default retry
                    if (matrixRetryTimeout < 0) {
                        snapshot.mRetryCount++;
                    }
                    // any event has a time life to avoid very old messages
                    long timeLife = 0;
                    // age < 0 means that the event time life is ignored
                    if (snapshot.mAge > 0) {
                        timeLife = System.currentTimeMillis() - snapshot.mAge;
                    }
                    if ((timeLife > MAX_MESSAGE_LIFETIME_MS) || (snapshot.mRetryCount > MAX_RETRIES)) {
                        snapshot.stopTimers();
                        mUnsentEventsMap.remove(apiCallback);
                        mUnsentEvents.remove(snapshot);
                        if (null != eventDescription) {
                            Log.d(LOG_TAG, "Cancel [" + eventDescription + "]");
                        }
                        isManaged = false;
                    } else {
                        isManaged = true;
                    }
                } else {
                    snapshot = new UnsentEventSnapshot();
                    try {
                        snapshot.mAge = ignoreEventTimeLifeInOffline ? -1 : System.currentTimeMillis();
                        snapshot.mRequestRetryCallBack = requestRetryCallBack;
                        snapshot.mRetryCount = 1;
                        snapshot.mEventDescription = eventDescription;
                        mUnsentEventsMap.put(apiCallback, snapshot);
                        mUnsentEvents.add(snapshot);
                        if (mbIsConnected || !ignoreEventTimeLifeInOffline) {
                            // the event has a life time
                            final UnsentEventSnapshot fSnapshot = snapshot;
                            fSnapshot.mLifeTimeTimer = new Timer();
                            fSnapshot.mLifeTimeTimer.schedule(new TimerTask() {

                                @Override
                                public void run() {
                                    try {
                                        if (null != eventDescription) {
                                            Log.d(LOG_TAG, "Cancel to send [" + eventDescription + "]");
                                        }
                                        fSnapshot.stopTimers();
                                        synchronized (mUnsentEventsMap) {
                                            mUnsentEventsMap.remove(apiCallback);
                                            mUnsentEvents.remove(fSnapshot);
                                        }
                                        triggerErrorCallback(mDataHandler, eventDescription, retrofitError, apiCallback);
                                    } catch (Exception e) {
                                        Log.e(LOG_TAG, "## onEventSendingFailed() : failure Msg=" + e.getMessage());
                                    }
                                }
                            }, MAX_MESSAGE_LIFETIME_MS);
                        } else if (ignoreEventTimeLifeInOffline) {
                            Log.d(LOG_TAG, "The request " + eventDescription + " will be sent when a network will be available");
                        }
                    } catch (Throwable throwable) {
                        Log.e(LOG_TAG, "## snapshot creation failed " + throwable.getMessage());
                        if (null != snapshot.mLifeTimeTimer) {
                            snapshot.mLifeTimeTimer.cancel();
                        }
                        mUnsentEventsMap.remove(apiCallback);
                        mUnsentEvents.remove(snapshot);
                        try {
                            triggerErrorCallback(mDataHandler, eventDescription, retrofitError, apiCallback);
                        } catch (Exception e) {
                            Log.e(LOG_TAG, "## onEventSendingFailed() : failure Msg=" + e.getMessage());
                        }
                    }
                    isManaged = true;
                }
                // retry to send the message ?
                if (isManaged) {
                    // 
                    if (mbIsConnected) {
                        int jitterTime = ((int) Math.pow(2, snapshot.mRetryCount)) + (Math.abs(new Random(System.currentTimeMillis()).nextInt()) % RETRY_JITTER_MS);
                        isManaged = snapshot.resendEventAfter((matrixRetryTimeout > 0) ? matrixRetryTimeout : jitterTime);
                    }
                }
            }
        }
    }
    if (!isManaged) {
        Log.d(LOG_TAG, "Cannot resend it");
        triggerErrorCallback(mDataHandler, eventDescription, retrofitError, apiCallback);
    }
}
Also used : Timer(java.util.Timer) TimerTask(java.util.TimerTask) Random(java.util.Random) UnrecognizedCertificateException(org.matrix.androidsdk.ssl.UnrecognizedCertificateException) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) UnrecognizedCertificateException(org.matrix.androidsdk.ssl.UnrecognizedCertificateException)

Aggregations

Random (java.util.Random)1 Timer (java.util.Timer)1 TimerTask (java.util.TimerTask)1 MatrixError (org.matrix.androidsdk.rest.model.MatrixError)1 UnrecognizedCertificateException (org.matrix.androidsdk.ssl.UnrecognizedCertificateException)1