FINERACT-1909: Retry feature for commands - no wrap for retryable exceptions

This commit is contained in:
jmarta
2023-11-03 16:56:23 +01:00
committed by Adam Saghy
parent 224dbdc040
commit a42f46957d
78 changed files with 375 additions and 446 deletions
@@ -35,7 +35,7 @@ import org.apache.fineract.accounting.closure.serialization.GLClosureCommandFrom
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.organisation.office.domain.Office;
import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper;
@@ -143,7 +143,7 @@ public class GLClosureWritePlatformServiceJpaRepositoryImpl implements GLClosure
}
log.error("Error occured.", dve);
throw new PlatformDataIntegrityException("error.msg.glClosure.unknown.data.integrity.issue",
throw ErrorHandler.getMappable(dve, "error.msg.glClosure.unknown.data.integrity.issue",
"Unknown data integrity issue with resource GL Closure: " + realCause.getMessage());
}
}
@@ -36,9 +36,8 @@ import org.apache.fineract.accounting.glaccount.domain.GLAccountRepositoryWrappe
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.NonTransientDataAccessException;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.stereotype.Service;
@@ -141,7 +140,7 @@ public class FinancialActivityAccountWritePlatformServiceImpl implements Financi
}
private void handleFinancialActivityAccountDataIntegrityIssues(final JsonCommand command, final Throwable realCause,
final NonTransientDataAccessException dve) {
final Exception dve) {
if (realCause.getMessage().contains("financial_activity_type")) {
final Integer financialActivityId = command
.integerValueSansLocaleOfParameterNamed(FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue());
@@ -149,19 +148,7 @@ public class FinancialActivityAccountWritePlatformServiceImpl implements Financi
}
log.error("Error occured.", dve);
throw new PlatformDataIntegrityException("error.msg.glAccount.unknown.data.integrity.issue",
"Unknown data integrity issue with resource GL Account: " + realCause.getMessage());
}
private void handleFinancialActivityAccountDataIntegrityIssues(JsonCommand command, Throwable realCause, PersistenceException dve) {
if (realCause.getMessage().contains("financial_activity_type")) {
final Integer financialActivityId = command
.integerValueSansLocaleOfParameterNamed(FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue());
throw new DuplicateFinancialActivityAccountFoundException(financialActivityId);
}
log.error("Error occured.", dve);
throw new PlatformDataIntegrityException("error.msg.glAccount.unknown.data.integrity.issue",
throw ErrorHandler.getMappable(dve, "error.msg.glAccount.unknown.data.integrity.issue",
"Unknown data integrity issue with resource GL Account: " + realCause.getMessage());
}
@@ -42,7 +42,7 @@ import org.apache.fineract.infrastructure.codes.domain.CodeValueRepositoryWrappe
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataIntegrityViolationException;
@@ -230,7 +230,7 @@ public class GLAccountWritePlatformServiceJpaRepositoryImpl implements GLAccount
}
LOG.error("Error occured.", dve);
throw new PlatformDataIntegrityException("error.msg.glAccount.unknown.data.integrity.issue",
throw ErrorHandler.getMappable(dve, "error.msg.glAccount.unknown.data.integrity.issue",
"Unknown data integrity issue with resource GL Account: " + realCause.getMessage());
}
@@ -26,6 +26,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.fineract.batch.domain.Header;
import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
/**
* Provides members to hold the basic information about the exceptions raised in commandStrategy classes.
@@ -48,11 +48,11 @@ import org.apache.fineract.batch.domain.BatchRequest;
import org.apache.fineract.batch.domain.BatchResponse;
import org.apache.fineract.batch.domain.Header;
import org.apache.fineract.batch.exception.BatchReferenceInvalidException;
import org.apache.fineract.batch.exception.ErrorHandler;
import org.apache.fineract.batch.exception.ErrorInfo;
import org.apache.fineract.batch.service.ResolutionHelper.BatchRequestNode;
import org.apache.fineract.infrastructure.core.domain.BatchRequestContextHolder;
import org.apache.fineract.infrastructure.core.exception.AbstractIdempotentCommandException;
import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.apache.fineract.infrastructure.core.filters.BatchCallHandler;
import org.apache.fineract.infrastructure.core.filters.BatchFilter;
import org.apache.fineract.infrastructure.core.filters.BatchRequestPreprocessor;
@@ -21,13 +21,13 @@ package org.apache.fineract.commands.service;
import static org.apache.fineract.commands.domain.CommandProcessingResultType.UNDER_PROCESSING;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.batch.exception.ErrorHandler;
import org.apache.fineract.batch.exception.ErrorInfo;
import org.apache.fineract.commands.domain.CommandSource;
import org.apache.fineract.commands.domain.CommandSourceRepository;
import org.apache.fineract.commands.domain.CommandWrapper;
import org.apache.fineract.commands.exception.CommandNotFoundException;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.apache.fineract.useradministration.domain.AppUser;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
@@ -20,7 +20,6 @@ package org.apache.fineract.commands.service;
import static org.apache.fineract.commands.domain.CommandProcessingResultType.ERROR;
import static org.apache.fineract.commands.domain.CommandProcessingResultType.PROCESSED;
import static org.apache.fineract.commands.domain.CommandProcessingResultType.UNDER_PROCESSING;
import static org.apache.http.HttpStatus.SC_OK;
import com.google.gson.Gson;
@@ -32,7 +31,6 @@ import java.util.HashMap;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.batch.exception.ErrorHandler;
import org.apache.fineract.batch.exception.ErrorInfo;
import org.apache.fineract.commands.domain.CommandProcessingResultType;
import org.apache.fineract.commands.domain.CommandSource;
@@ -47,6 +45,7 @@ import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import org.apache.fineract.infrastructure.core.domain.BatchRequestContextHolder;
import org.apache.fineract.infrastructure.core.domain.FineractRequestContextHolder;
import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.apache.fineract.infrastructure.core.exception.IdempotentCommandProcessFailedException;
import org.apache.fineract.infrastructure.core.exception.IdempotentCommandProcessSucceedException;
import org.apache.fineract.infrastructure.core.exception.IdempotentCommandProcessUnderProcessingException;
@@ -54,6 +54,9 @@ public abstract class AbstractPlatformException extends RuntimeException {
}
private static Throwable findThrowableCause(Object[] defaultUserMessageArgs) {
if (defaultUserMessageArgs == null) {
return null;
}
for (Object defaultUserMessageArg : defaultUserMessageArgs) {
if (defaultUserMessageArg instanceof Throwable) {
return (Throwable) defaultUserMessageArg;
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.batch.exception;
package org.apache.fineract.infrastructure.core.exception;
import static org.springframework.core.ResolvableType.forClassWithGenerics;
@@ -36,9 +36,8 @@ import lombok.extern.slf4j.Slf4j;
import net.fortuna.ical4j.validate.ValidationException;
import org.apache.commons.collections4.SetUtils;
import org.apache.fineract.batch.domain.Header;
import org.apache.fineract.batch.exception.ErrorInfo;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.infrastructure.core.exceptionmapper.DefaultExceptionMapper;
import org.apache.fineract.infrastructure.core.exceptionmapper.FineractExceptionMapper;
import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
@@ -108,40 +107,45 @@ public final class ErrorHandler {
return new ErrorInfo(response.getStatus(), errorCode, msg instanceof String ? (String) msg : JSON_HELPER.toJson(msg), batchHeaders);
}
public RuntimeException getMappable(@NotNull Throwable thr) {
public static RuntimeException getMappable(@NotNull Throwable thr) {
return getMappable(thr, null, null, null);
}
public RuntimeException getMappable(@NotNull Throwable t, String msgCode, String defaultMsg, String param,
public static RuntimeException getMappable(@NotNull Throwable thr, String msgCode, String defaultMsg) {
return getMappable(thr, msgCode, defaultMsg, null);
}
public static RuntimeException getMappable(@NotNull Throwable t, String msgCode, String defaultMsg, String param,
final Object... defaultMsgArgs) {
String msg = defaultMsg == null ? t.getMessage() : defaultMsg;
param = param == null ? "unknown" : param;
String codePfx = "error.msg" + (param == null ? "" : ("." + param));
Object[] args = defaultMsgArgs == null ? new Object[] { t } : defaultMsgArgs;
if (t instanceof NestedRuntimeException nre) {
Throwable cause = nre.getMostSpecificCause();
msg = cause.getMessage();
msg = defaultMsg == null ? cause.getMessage() : defaultMsg;
if (nre instanceof NonTransientDataAccessException) {
msgCode = msgCode == null ? "error.msg." + param + ".data.integrity.issue" : msgCode;
return new PlatformDataIntegrityException(msgCode, msg, param, defaultMsgArgs);
msgCode = msgCode == null ? codePfx + ".data.integrity.issue" : msgCode;
return new PlatformDataIntegrityException(msgCode, msg, param, args);
}
}
if (t instanceof ValidationException) {
msgCode = msgCode == null ? "error.msg.validation." + param + ".error" : msgCode;
msgCode = msgCode == null ? codePfx + ".validation.error" : msgCode;
return new PlatformApiDataValidationException(List.of(ApiParameterError.parameterError(msgCode, msg, param, defaultMsgArgs)));
}
if (t instanceof PersistenceException) {
msgCode = msgCode == null ? "error.msg.persistence." + param + ".error" : msgCode;
return new PlatformDataIntegrityException(msgCode, msg, param, defaultMsgArgs);
msgCode = msgCode == null ? codePfx + ".persistence.error" : msgCode;
return new PlatformDataIntegrityException(msgCode, msg, param, args);
}
if (t instanceof AuthenticationException) {
msgCode = msgCode == null ? "error.msg.authentication." + param + ".error" : msgCode;
return new PlatformDataIntegrityException(msgCode, msg, param, defaultMsgArgs);
msgCode = msgCode == null ? codePfx + ".authentication.error" : msgCode;
return new PlatformDataIntegrityException(msgCode, msg, param, args);
}
if (t instanceof RuntimeException re) {
return re;
}
if (t instanceof ParseException) {
msgCode = msgCode == null ? "error.msg.parse." + param + ".error" : msgCode;
return new PlatformDataIntegrityException(msgCode, msg, param, defaultMsgArgs);
msgCode = msgCode == null ? codePfx + ".parse.error" : msgCode;
return new PlatformDataIntegrityException(msgCode, msg, param, args);
}
return new RuntimeException(msg, t);
}
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import java.util.InputMismatchException;
import java.util.Map;
import java.util.NoSuchElementException;
import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.apache.fineract.infrastructure.core.exceptionmapper.DefaultExceptionMapper;
import org.apache.fineract.infrastructure.core.exceptionmapper.FineractExceptionMapper;
import org.junit.jupiter.api.Assertions;