diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java
index 6bcc469..d0d61d2 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java
@@ -150,7 +150,7 @@ public abstract class OperationControlCallback extends OperationCallbackBase<Pay
} catch (final RuntimeException e) {
// Attempts to set the retry date in context if needed.
executePluginOnFailureCallsAndSetRetryDate(paymentControlContext);
- throw e;
+ throw new OperationException(e, OperationResult.EXCEPTION);
}
}
});
@@ -158,9 +158,11 @@ public abstract class OperationControlCallback extends OperationCallbackBase<Pay
@Override
protected OperationException unwrapExceptionFromDispatchedTask(final PaymentStateContext paymentStateContext, final Exception e) {
-
// If this is an ExecutionException we attempt to extract the cause first
- final Throwable originalExceptionOrCause = e instanceof ExecutionException ? MoreObjects.firstNonNull(e.getCause(), e) : e;
+ final Throwable originalExceptionOrCausePossiblyOperationException = e instanceof ExecutionException ? MoreObjects.firstNonNull(e.getCause(), e) : e;
+
+ // Unwrap OperationException too (doOperationCallback wraps exceptions in OperationException)
+ final Throwable originalExceptionOrCause = originalExceptionOrCausePossiblyOperationException instanceof OperationException ? MoreObjects.firstNonNull(originalExceptionOrCausePossiblyOperationException.getCause(), originalExceptionOrCausePossiblyOperationException) : originalExceptionOrCausePossiblyOperationException;
if (originalExceptionOrCause instanceof OperationException) {
return (OperationException) originalExceptionOrCause;
@@ -170,10 +172,10 @@ public abstract class OperationControlCallback extends OperationCallbackBase<Pay
logger.warn("Call TIMEOUT for accountId='{}'", paymentStateContext.getAccount().getId());
} else if (originalExceptionOrCause instanceof InterruptedException) {
logger.warn("Call was interrupted for accountId='{}'", paymentStateContext.getAccount().getId());
- } else /* most probably RuntimeException */ {
+ } else {
logger.warn("Operation failed for accountId='{}'", paymentStateContext.getAccount().getId(), e);
}
- return new OperationException(e, getOperationResultOnException(paymentStateContext));
+ return new OperationException(originalExceptionOrCause, getOperationResultOnException(paymentStateContext));
}
private OperationResult getOperationResultOnException(final PaymentStateContext paymentStateContext) {
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentOperation.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentOperation.java
index 454e025..9388e2f 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentOperation.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentOperation.java
@@ -88,25 +88,26 @@ public abstract class PaymentOperation extends OperationCallbackBase<PaymentTran
@Override
protected OperationException unwrapExceptionFromDispatchedTask(final PaymentStateContext paymentStateContext, final Exception e) {
-
// If this is an ExecutionException we attempt to extract the cause first
- final Throwable originalExceptionOrCause = e instanceof ExecutionException ? MoreObjects.firstNonNull(e.getCause(), e) : e;
+ final Throwable originalExceptionOrCausePossiblyOperationException = e instanceof ExecutionException ? MoreObjects.firstNonNull(e.getCause(), e) : e;
+
+ // Unwrap OperationException too (doOperationCallback wraps exceptions in OperationException)
+ final Throwable originalExceptionOrCause = originalExceptionOrCausePossiblyOperationException instanceof OperationException ? MoreObjects.firstNonNull(originalExceptionOrCausePossiblyOperationException.getCause(), originalExceptionOrCausePossiblyOperationException) : originalExceptionOrCausePossiblyOperationException;
//
// Any case of exception (checked or runtime) should lead to a TransactionStatus.UNKNOWN (and a XXX_ERRORED payment state).
// In order to reach that state we create PaymentTransactionInfoPlugin with an PaymentPluginStatus.UNDEFINED status (and an OperationResult.EXCEPTION).
//
if (originalExceptionOrCause instanceof LockFailedException) {
- logger.warn("Failed to lock account {}", paymentStateContext.getAccount().getExternalKey());
+ logger.warn("Failed to lock accountExternalKey='{}'", paymentStateContext.getAccount().getExternalKey());
} else if (originalExceptionOrCause instanceof TimeoutException) {
- logger.error("Plugin call TIMEOUT for account {}", paymentStateContext.getAccount().getExternalKey());
+ logger.warn("Plugin call TIMEOUT for accountExternalKey='{}'", paymentStateContext.getAccount().getExternalKey());
} else if (originalExceptionOrCause instanceof InterruptedException) {
- logger.error("Plugin call was interrupted for account {}", paymentStateContext.getAccount().getExternalKey());
+ logger.warn("Plugin call was interrupted for accountExternalKey='{}'", paymentStateContext.getAccount().getExternalKey());
} else {
- logger.warn("Payment plugin call threw an exception for account {}", paymentStateContext.getAccount().getExternalKey(), originalExceptionOrCause);
+ logger.warn("Payment plugin call threw an exception for accountExternalKey='{}'", paymentStateContext.getAccount().getExternalKey(), originalExceptionOrCause);
}
return convertToUnknownTransactionStatusAndErroredPaymentState(originalExceptionOrCause);
-
}
//