package com.enigmabridge.comm.retry;

/**
 * Root exception for all retry based exceptions.
 *
 * Created by dusanklinec on 21.07.16.
 */
public class EBRetryException extends Exception {
    /**
     * Error indicated in onFail() notify.
     * Mostly it is an exception that caused job to fail.
     */
    protected Object error;

    /**
     * Retry mechanism throwing this exception.
     */
    protected EBRetry retry;

    public EBRetryException() {
    }

    public EBRetryException(String message) {
        super(message);
    }

    public EBRetryException(String message, Throwable cause) {
        super(message, cause);
    }

    public EBRetryException(Throwable cause) {
        super(cause);
    }

    public EBRetryException(Object error, EBRetry retry) {
        this.error = error;
        this.retry = retry;
    }

    public EBRetryException(String message, Object error, EBRetry retry) {
        super(message);
        this.error = error;
        this.retry = retry;
    }

    public EBRetryException(String message, Throwable cause, Object error, EBRetry retry) {
        super(message, cause);
        this.error = error;
        this.retry = retry;
    }

    public EBRetryException(Throwable cause, Object error, EBRetry retry) {
        super(cause);
        this.error = error;
        this.retry = retry;
    }

    public Object getError() {
        return error;
    }

    public EBRetry getRetry() {
        return retry;
    }

    public void setError(Object error) {
        this.error = error;
    }

    public void setRetry(EBRetry retry) {
        this.retry = retry;
    }

    /**
     * Return an trhowable instance if the error object is of Throwable type.
     * Null otherwise.
     *
     * @return Throwable or null
     */
    public Throwable getErrorCauseIfAny(){
        return error != null && error instanceof Throwable ? (Throwable) error : null;
    }

    /**
     * Overridden getCause that takes error object into account also.
     * Original cause has the precedence, if null, error object is tested if is Throwable instance.
     *
     * @return cause or null
     */
    @Override
    public synchronized Throwable getCause() {
        final Throwable cause = super.getCause();
        if (cause != null){
            return cause;
        }

        return getErrorCauseIfAny();
    }
}

@@ -821,32 +821,67 @@
 .retry = retry;%0A
+        updateCauseIfApplicable();%0A
     %7D%0A%0A    publi
@@ -1018,32 +1018,67 @@
 .retry = retry;%0A
+        updateCauseIfApplicable();%0A
     %7D%0A%0A    publi
@@ -1545,42 +1545,47 @@
    p
-ublic void setError(Object error) 
+rotected void updateCauseIfApplicable()
 %7B%0A  
@@ -1582,32 +1582,36 @@
 able()%7B%0A        
+if (
 this.error = err
@@ -1610,91 +1610,127 @@
 or =
- error;
+= null %7C%7C !(this.error instanceof Throwable))%7B
 %0A    
-%7D%0A%0A
     
-public void setRetry(EBRetry retry) %7B%0A        this.retry = retry
+    return;%0A        %7D%0A%0A        initCause((Throwable) this.error)
 ;%0A  

update cause for retry exception