This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 051b37c4b FINERACT-1971: Enhanced error logging: Optimistic lock
exception handling + log most specific exception
051b37c4b is described below
commit 051b37c4b3c0eae3f4f1c2cc42cdfcdfd1d683b4
Author: Adam Saghy <[email protected]>
AuthorDate: Tue Feb 20 14:24:16 2024 +0100
FINERACT-1971: Enhanced error logging: Optimistic lock exception handling +
log most specific exception
---
.../infrastructure/core/exception/ErrorHandler.java | 20 +++++++++++++++++---
.../HttpMessageNotReadableErrorController.java | 2 +-
.../exceptionmapper/AccessDeniedExceptionMapper.java | 3 ++-
.../BadCredentialsExceptionMapper.java | 3 ++-
.../exceptionmapper/BusinessStepExceptionMapper.java | 3 ++-
.../BusinessStepNotBelongsToJobExceptionMapper.java | 3 ++-
.../ConcurrencyFailureExceptionMapper.java | 3 ++-
.../core/exceptionmapper/DefaultExceptionMapper.java | 3 ++-
.../IdempotentCommandExceptionMapper.java | 3 ++-
.../InvalidInstanceTypeMethodExceptionMapper.java | 3 ++-
.../exceptionmapper/InvalidJsonExceptionMapper.java | 3 ++-
.../InvalidTenantIdentifierExceptionMapper.java | 3 ++-
...ava => JakartaOptimisticLockExceptionMapper.java} | 11 +++++------
.../JobIsNotFoundOrNotEnabledExceptionMapper.java | 3 ++-
...er.java => JpaOptimisticLockExceptionMapper.java} | 13 ++++++-------
.../exceptionmapper/JsonPathExceptionMapper.java | 3 ++-
.../exceptionmapper/JsonSyntaxExceptionMapper.java | 3 ++-
.../MalformedJsonExceptionMapper.java | 3 ++-
.../NoAuthorizationExceptionMapper.java | 3 ++-
.../exceptionmapper/OAuth2ExceptionEntryPoint.java | 3 ++-
.../OptimisticLockExceptionMapper.java | 5 ++---
.../PlatformApiDataValidationExceptionMapper.java | 3 ++-
.../PlatformDataIntegrityExceptionMapper.java | 3 ++-
.../PlatformDomainRuleExceptionMapper.java | 3 ++-
.../PlatformInternalServerExceptionMapper.java | 3 ++-
...equestBodyItemLimitValidationExceptionMapper.java | 3 ++-
.../PlatformResourceNotFoundExceptionMapper.java | 3 ++-
.../PlatformServiceUnavailableExceptionMapper.java | 3 ++-
...ollbackTransactionNotApprovedExceptionMapper.java | 3 ++-
.../UnAuthenticatedUserExceptionMapper.java | 3 ++-
.../UnrecognizedQueryParamExceptionMapper.java | 3 ++-
.../UnsupportedCommandExceptionMapper.java | 3 ++-
.../UnsupportedParameterExceptionMapper.java | 3 ++-
...nalAssetOwnerInitiateTransferExceptionMapper.java | 3 ++-
.../LinkedAccountRequiredExceptionMapper.java | 2 +-
.../exception/LoanIdsHardLockedExceptionMapper.java | 2 +-
...MultiDisbursementDataRequiredExceptionMapper.java | 2 +-
...nAccountLockCannotBeOverruledExceptionMapper.java | 3 ++-
.../src/main/resources/application.properties | 6 +++---
39 files changed, 97 insertions(+), 56 deletions(-)
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/ErrorHandler.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/ErrorHandler.java
index 4ce0e98a8..f6ffb431c 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/ErrorHandler.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/ErrorHandler.java
@@ -44,6 +44,7 @@ import
org.apache.fineract.infrastructure.core.data.ApiParameterError;
import
org.apache.fineract.infrastructure.core.exceptionmapper.DefaultExceptionMapper;
import
org.apache.fineract.infrastructure.core.exceptionmapper.FineractExceptionMapper;
import
org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
+import org.eclipse.persistence.exceptions.OptimisticLockException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.NestedRuntimeException;
@@ -177,12 +178,17 @@ public final class ErrorHandler {
if (nre instanceof NonTransientDataAccessException) {
msgCode = msgCode == null ? codePfx + ".data.integrity.issue"
: msgCode;
return new PlatformDataIntegrityException(msgCode, msg, param,
args);
+ } else if (cause instanceof OptimisticLockException) {
+ return (RuntimeException) cause;
}
}
if (t instanceof ValidationException) {
msgCode = msgCode == null ? codePfx + ".validation.error" :
msgCode;
return new
PlatformApiDataValidationException(List.of(ApiParameterError.parameterError(msgCode,
msg, param, defaultMsgArgs)));
}
+ if (t instanceof jakarta.persistence.OptimisticLockException) {
+ return (RuntimeException) t;
+ }
if (t instanceof PersistenceException) {
msgCode = msgCode == null ? codePfx + ".persistence.error" :
msgCode;
return new PlatformDataIntegrityException(msgCode, msg, param,
args);
@@ -191,13 +197,13 @@ public final class ErrorHandler {
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 ? codePfx + ".parse.error" : msgCode;
return new PlatformDataIntegrityException(msgCode, msg, param,
args);
}
+ if (t instanceof RuntimeException re) {
+ return re;
+ }
return new RuntimeException(msg, t);
}
@@ -208,4 +214,12 @@ public final class ErrorHandler {
return Set.of(array);
}
}
+
+ public static Throwable findMostSpecificException(Exception exception) {
+ Throwable mostSpecificException = exception;
+ while (mostSpecificException.getCause() != null) {
+ mostSpecificException = mostSpecificException.getCause();
+ }
+ return mostSpecificException;
+ }
}
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/HttpMessageNotReadableErrorController.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/HttpMessageNotReadableErrorController.java
index bf04e8df6..8bd56c399 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/HttpMessageNotReadableErrorController.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/HttpMessageNotReadableErrorController.java
@@ -39,7 +39,7 @@ public class HttpMessageNotReadableErrorController implements
ExceptionMapper<Ht
public Response toResponse(HttpMessageNotReadableException exception) {
final String globalisationMessageCode = "error.msg.invalid.json.data";
final String defaultUserMessage = "The referenced JSON data is
invalid, validate date format as yyyy-MM-dd or other cases like String instead
of Number";
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiParameterError error =
ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/AccessDeniedExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/AccessDeniedExceptionMapper.java
index 4c944c223..d0738ce3e 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/AccessDeniedExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/AccessDeniedExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.context.annotation.Scope;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Component;
@@ -46,7 +47,7 @@ public class AccessDeniedExceptionMapper implements
ExceptionMapper<AccessDenied
// Status code 403 really reads as:
// "Authenticated - but not authorized":
final String defaultUserMessage = exception.getMessage();
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
return
Response.status(Status.FORBIDDEN).entity(ApiGlobalErrorResponse.unAuthorized(defaultUserMessage))
.type(MediaType.APPLICATION_JSON).build();
}
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BadCredentialsExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BadCredentialsExceptionMapper.java
index c00e84645..a5314e4ba 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BadCredentialsExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BadCredentialsExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.context.annotation.Scope;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.stereotype.Component;
@@ -44,7 +45,7 @@ public class BadCredentialsExceptionMapper implements
ExceptionMapper<BadCredent
@Override
public Response toResponse(@SuppressWarnings("unused") final
BadCredentialsException exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
return
Response.status(Status.UNAUTHORIZED).entity(ApiGlobalErrorResponse.unAuthenticated()).type(MediaType.APPLICATION_JSON)
.build();
}
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepExceptionMapper.java
index 29432325e..64111e91b 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.cob.exceptions.BusinessStepException;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.stereotype.Component;
@Provider
@@ -36,7 +37,7 @@ public class BusinessStepExceptionMapper implements
ExceptionMapper<BusinessStep
public Response toResponse(BusinessStepException exception) {
final String globalisationMessageCode =
"error.msg.invalid.request.body";
final String defaultUserMessage = exception.getMessage();
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiParameterError error =
ApiParameterError.parameterError(globalisationMessageCode, defaultUserMessage,
"stepName");
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepNotBelongsToJobExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepNotBelongsToJobExceptionMapper.java
index 731fc5d42..618b78e3f 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepNotBelongsToJobExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepNotBelongsToJobExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.cob.exceptions.BusinessStepNotBelongsToJobException;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.stereotype.Component;
@Provider
@@ -36,7 +37,7 @@ public class BusinessStepNotBelongsToJobExceptionMapper
implements ExceptionMapp
public Response toResponse(BusinessStepNotBelongsToJobException exception)
{
final String globalisationMessageCode =
"error.msg.invalid.request.body";
final String defaultUserMessage = "One of the provided Business Steps
does not belong to the provided Job Name.";
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiParameterError error =
ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/ConcurrencyFailureExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/ConcurrencyFailureExceptionMapper.java
index 0d63157cd..bf3d6b355 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/ConcurrencyFailureExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/ConcurrencyFailureExceptionMapper.java
@@ -26,6 +26,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.context.annotation.Scope;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
@@ -43,7 +44,7 @@ public class ConcurrencyFailureExceptionMapper implements
FineractExceptionMappe
@Override
public Response toResponse(final ConcurrencyFailureException exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
String type;
String identifier;
if (exception instanceof ObjectOptimisticLockingFailureException olex)
{
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/DefaultExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/DefaultExceptionMapper.java
index e6a283ce2..17c2fa094 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/DefaultExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/DefaultExceptionMapper.java
@@ -26,6 +26,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -41,7 +42,7 @@ public class DefaultExceptionMapper implements
FineractExceptionMapper, Exceptio
@Override
public Response toResponse(RuntimeException exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
return Response.status(SC_INTERNAL_SERVER_ERROR)
.entity(Map.of("Exception",
ObjectUtils.defaultIfNull(exception.getMessage(), "No error message
available")))
.type(MediaType.APPLICATION_JSON).build();
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandExceptionMapper.java
index df17e3d13..b969e4e19 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandExceptionMapper.java
@@ -28,6 +28,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import
org.apache.fineract.infrastructure.core.exception.AbstractIdempotentCommandException;
+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;
@@ -46,7 +47,7 @@ public class IdempotentCommandExceptionMapper implements
FineractExceptionMapper
@Override
public Response toResponse(final AbstractIdempotentCommandException
exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
Integer status = null;
if (exception instanceof IdempotentCommandProcessSucceedException pse)
{
Integer statusCode = pse.getStatusCode();
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidInstanceTypeMethodExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidInstanceTypeMethodExceptionMapper.java
index dfae947a1..6fea99246 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidInstanceTypeMethodExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidInstanceTypeMethodExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import
org.apache.fineract.infrastructure.security.exception.InvalidInstanceTypeMethodException;
import org.springframework.stereotype.Component;
@@ -39,7 +40,7 @@ public class InvalidInstanceTypeMethodExceptionMapper
implements ExceptionMapper
@Override
public Response toResponse(final InvalidInstanceTypeMethodException
exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
ApiGlobalErrorResponse errorResponse =
ApiGlobalErrorResponse.invalidInstanceTypeMethod(exception.getMethod());
return
Response.status(Status.METHOD_NOT_ALLOWED).entity(errorResponse).type(MediaType.APPLICATION_JSON).build();
}
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidJsonExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidJsonExceptionMapper.java
index 35f07848e..64610409c 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidJsonExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidJsonExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -42,7 +43,7 @@ public class InvalidJsonExceptionMapper implements
ExceptionMapper<InvalidJsonEx
public Response toResponse(@SuppressWarnings("unused") final
InvalidJsonException exception) {
final String globalisationMessageCode =
"error.msg.invalid.request.body";
final String defaultUserMessage = "The JSON provided in the body of
the request is invalid or missing.";
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiParameterError error =
ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidTenantIdentifierExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidTenantIdentifierExceptionMapper.java
index 6751ed891..956f47cc6 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidTenantIdentifierExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidTenantIdentifierExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import
org.apache.fineract.infrastructure.security.exception.InvalidTenantIdentifierException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -44,7 +45,7 @@ public class InvalidTenantIdentifierExceptionMapper
implements ExceptionMapper<I
@Override
public Response toResponse(@SuppressWarnings("unused") final
InvalidTenantIdentifierException exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
return
Response.status(Status.UNAUTHORIZED).entity(ApiGlobalErrorResponse.invalidTenantIdentifier())
.type(MediaType.APPLICATION_JSON).build();
}
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JakartaOptimisticLockExceptionMapper.java
similarity index 83%
copy from
fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java
copy to
fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JakartaOptimisticLockExceptionMapper.java
index 0417fe520..f773b2baf 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JakartaOptimisticLockExceptionMapper.java
@@ -20,14 +20,14 @@ package
org.apache.fineract.infrastructure.core.exceptionmapper;
import static org.apache.http.HttpStatus.SC_CONFLICT;
+import jakarta.persistence.OptimisticLockException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
-import org.eclipse.persistence.exceptions.OptimisticLockException;
-import org.springframework.context.annotation.Scope;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.springframework.stereotype.Component;
@@ -37,14 +37,13 @@ import org.springframework.stereotype.Component;
*/
@Provider
@Component
-@Scope("singleton")
@Slf4j
-public class OptimisticLockExceptionMapper implements FineractExceptionMapper,
ExceptionMapper<OptimisticLockException> {
+public class JakartaOptimisticLockExceptionMapper implements
FineractExceptionMapper, ExceptionMapper<OptimisticLockException> {
@Override
public Response toResponse(final OptimisticLockException exception) {
- log.warn("Exception occurred", exception);
- String type = exception.getQuery() == null ? "unknown" : "query";
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
+ String type = "optimistic lock";
String identifier = "unknown";
final ApiGlobalErrorResponse dataIntegrityError =
ApiGlobalErrorResponse.conflict(type, identifier);
return
Response.status(SC_CONFLICT).entity(dataIntegrityError).type(MediaType.APPLICATION_JSON).build();
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JobIsNotFoundOrNotEnabledExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JobIsNotFoundOrNotEnabledExceptionMapper.java
index 73b71b3e8..2ff0be66c 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JobIsNotFoundOrNotEnabledExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JobIsNotFoundOrNotEnabledExceptionMapper.java
@@ -24,6 +24,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import
org.apache.fineract.infrastructure.core.exception.JobIsNotFoundOrNotEnabledException;
import org.springframework.stereotype.Component;
@@ -34,7 +35,7 @@ public class JobIsNotFoundOrNotEnabledExceptionMapper
implements ExceptionMapper
@Override
public Response toResponse(JobIsNotFoundOrNotEnabledException exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
return Response.status(Response.Status.FORBIDDEN)
.entity(ApiGlobalErrorResponse.jobIsDisabled(exception.getGlobalisationMessageCode(),
exception.getDefaultUserMessage()))
.type(MediaType.APPLICATION_JSON).build();
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JpaOptimisticLockExceptionMapper.java
similarity index 78%
copy from
fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java
copy to
fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JpaOptimisticLockExceptionMapper.java
index 0417fe520..a236c44f2 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JpaOptimisticLockExceptionMapper.java
@@ -26,9 +26,9 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
-import org.eclipse.persistence.exceptions.OptimisticLockException;
-import org.springframework.context.annotation.Scope;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
+import org.springframework.orm.jpa.JpaOptimisticLockingFailureException;
import org.springframework.stereotype.Component;
/**
@@ -37,14 +37,13 @@ import org.springframework.stereotype.Component;
*/
@Provider
@Component
-@Scope("singleton")
@Slf4j
-public class OptimisticLockExceptionMapper implements FineractExceptionMapper,
ExceptionMapper<OptimisticLockException> {
+public class JpaOptimisticLockExceptionMapper implements
FineractExceptionMapper, ExceptionMapper<JpaOptimisticLockingFailureException> {
@Override
- public Response toResponse(final OptimisticLockException exception) {
- log.warn("Exception occurred", exception);
- String type = exception.getQuery() == null ? "unknown" : "query";
+ public Response toResponse(final JpaOptimisticLockingFailureException
exception) {
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
+ String type = "optimistic lock";
String identifier = "unknown";
final ApiGlobalErrorResponse dataIntegrityError =
ApiGlobalErrorResponse.conflict(type, identifier);
return
Response.status(SC_CONFLICT).entity(dataIntegrityError).type(MediaType.APPLICATION_JSON).build();
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonPathExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonPathExceptionMapper.java
index 3ce0affde..7f8da34a2 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonPathExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonPathExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -38,7 +39,7 @@ public class JsonPathExceptionMapper implements
ExceptionMapper<JsonPathExceptio
public Response toResponse(JsonPathException exception) {
final String globalisationMessageCode = "error.msg.invalid.json.path";
final String defaultUserMessage = "The referenced JSON path is
invalid.";
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiParameterError error =
ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonSyntaxExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonSyntaxExceptionMapper.java
index f32e5517b..a9dfb054d 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonSyntaxExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonSyntaxExceptionMapper.java
@@ -26,6 +26,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -42,7 +43,7 @@ public class JsonSyntaxExceptionMapper implements
ExceptionMapper<JsonSyntaxExce
public Response toResponse(final JsonSyntaxException exception) {
final String globalisationMessageCode =
"error.msg.invalid.request.body";
final String defaultUserMessage = "The JSON syntax provided in the
body of the request is invalid: " + exception.getMessage();
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiParameterError error =
ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/MalformedJsonExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/MalformedJsonExceptionMapper.java
index fd650c5da..b85bcdcde 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/MalformedJsonExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/MalformedJsonExceptionMapper.java
@@ -26,6 +26,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -42,7 +43,7 @@ public class MalformedJsonExceptionMapper implements
ExceptionMapper<MalformedJs
public Response toResponse(@SuppressWarnings("unused") final
MalformedJsonException exception) {
final String globalisationMessageCode =
"error.msg.invalid.request.body";
final String defaultUserMessage = "The JSON provided in the body of
the request is invalid or missing.";
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiParameterError error =
ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/NoAuthorizationExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/NoAuthorizationExceptionMapper.java
index af35c839a..facef9f13 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/NoAuthorizationExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/NoAuthorizationExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import
org.apache.fineract.infrastructure.security.exception.NoAuthorizationException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -47,7 +48,7 @@ public class NoAuthorizationExceptionMapper implements
ExceptionMapper<NoAuthori
// Status code 403 really reads as:
// "Authenticated - but not authorized":
final String defaultUserMessage = exception.getMessage();
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
return
Response.status(Status.FORBIDDEN).entity(ApiGlobalErrorResponse.unAuthorized(defaultUserMessage))
.type(MediaType.APPLICATION_JSON).build();
}
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OAuth2ExceptionEntryPoint.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OAuth2ExceptionEntryPoint.java
index cb247858d..451581d96 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OAuth2ExceptionEntryPoint.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OAuth2ExceptionEntryPoint.java
@@ -24,6 +24,7 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
@@ -33,7 +34,7 @@ public class OAuth2ExceptionEntryPoint implements
AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse
response, AuthenticationException exception)
throws ServletException {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
ApiGlobalErrorResponse errorResponse =
ApiGlobalErrorResponse.unAuthenticated();
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java
index 0417fe520..b170c8da2 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java
@@ -26,8 +26,8 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.eclipse.persistence.exceptions.OptimisticLockException;
-import org.springframework.context.annotation.Scope;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.springframework.stereotype.Component;
@@ -37,13 +37,12 @@ import org.springframework.stereotype.Component;
*/
@Provider
@Component
-@Scope("singleton")
@Slf4j
public class OptimisticLockExceptionMapper implements FineractExceptionMapper,
ExceptionMapper<OptimisticLockException> {
@Override
public Response toResponse(final OptimisticLockException exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
String type = exception.getQuery() == null ? "unknown" : "query";
String identifier = "unknown";
final ApiGlobalErrorResponse dataIntegrityError =
ApiGlobalErrorResponse.conflict(type, identifier);
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformApiDataValidationExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformApiDataValidationExceptionMapper.java
index 0fb62b182..707bb8419 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformApiDataValidationExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformApiDataValidationExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -45,7 +46,7 @@ public class PlatformApiDataValidationExceptionMapper
@Override
public Response toResponse(final PlatformApiDataValidationException
exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiGlobalErrorResponse dataValidationErrorResponse =
ApiGlobalErrorResponse
.badClientRequest(exception.getGlobalisationMessageCode(),
exception.getDefaultUserMessage(), exception.getErrors());
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDataIntegrityExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDataIntegrityExceptionMapper.java
index 54e6a2b30..d67d3c59a 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDataIntegrityExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDataIntegrityExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import
org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -44,7 +45,7 @@ public class PlatformDataIntegrityExceptionMapper implements
FineractExceptionMa
@Override
public Response toResponse(final PlatformDataIntegrityException exception)
{
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiGlobalErrorResponse dataIntegrityError =
ApiGlobalErrorResponse.dataIntegrityError(exception.getGlobalisationMessageCode(),
exception.getDefaultUserMessage(),
exception.getParameterName(), exception.getDefaultUserMessageArgs());
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDomainRuleExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDomainRuleExceptionMapper.java
index 9b7fac95e..721bb4984 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDomainRuleExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDomainRuleExceptionMapper.java
@@ -26,6 +26,7 @@ import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
import
org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -44,7 +45,7 @@ public class PlatformDomainRuleExceptionMapper implements
FineractExceptionMappe
@Override
public Response toResponse(final AbstractPlatformDomainRuleException
exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiGlobalErrorResponse notFoundErrorResponse =
ApiGlobalErrorResponse.domainRuleViolation(
exception.getGlobalisationMessageCode(),
exception.getDefaultUserMessage(), exception.getDefaultUserMessageArgs());
// request understood but not carried out due to it violating some
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformInternalServerExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformInternalServerExceptionMapper.java
index e0231f097..68f551b0c 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformInternalServerExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformInternalServerExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import
org.apache.fineract.infrastructure.core.exception.PlatformInternalServerException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -43,7 +44,7 @@ public class PlatformInternalServerExceptionMapper implements
FineractExceptionM
@Override
public Response toResponse(final PlatformInternalServerException
exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiGlobalErrorResponse notFoundErrorResponse =
ApiGlobalErrorResponse.serverSideError(exception.getGlobalisationMessageCode(),
exception.getDefaultUserMessage(),
exception.getDefaultUserMessageArgs());
return
Response.status(Status.INTERNAL_SERVER_ERROR).entity(notFoundErrorResponse).type(MediaType.APPLICATION_JSON).build();
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformRequestBodyItemLimitValidationExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformRequestBodyItemLimitValidationExceptionMapper.java
index c0a875c6a..4e67cb356 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformRequestBodyItemLimitValidationExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformRequestBodyItemLimitValidationExceptionMapper.java
@@ -24,6 +24,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import
org.apache.fineract.infrastructure.core.exception.PlatformRequestBodyItemLimitValidationException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -38,7 +39,7 @@ public class
PlatformRequestBodyItemLimitValidationExceptionMapper
@Override
public Response toResponse(PlatformRequestBodyItemLimitValidationException
exception) {
String globalisationMessage =
"error.msg.validation.request.body.item.limit.validation";
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiGlobalErrorResponse badRequestErrorResponse =
ApiGlobalErrorResponse.badClientRequest(globalisationMessage,
exception.getMessage());
return
Response.status(Response.Status.BAD_REQUEST).entity(badRequestErrorResponse).type(MediaType.APPLICATION_JSON).build();
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformResourceNotFoundExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformResourceNotFoundExceptionMapper.java
index 56ba36497..bbdc0053b 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformResourceNotFoundExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformResourceNotFoundExceptionMapper.java
@@ -26,6 +26,7 @@ import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
import
org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -45,7 +46,7 @@ public class PlatformResourceNotFoundExceptionMapper
@Override
public Response toResponse(final AbstractPlatformResourceNotFoundException
exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiGlobalErrorResponse notFoundErrorResponse =
ApiGlobalErrorResponse.notFound(exception.getGlobalisationMessageCode(),
exception.getDefaultUserMessage(),
exception.getDefaultUserMessageArgs());
return
Response.status(Status.NOT_FOUND).entity(notFoundErrorResponse).type(MediaType.APPLICATION_JSON).build();
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformServiceUnavailableExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformServiceUnavailableExceptionMapper.java
index 38f4074b2..6248dc1d6 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformServiceUnavailableExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformServiceUnavailableExceptionMapper.java
@@ -26,6 +26,7 @@ import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
import
org.apache.fineract.infrastructure.core.exception.AbstractPlatformServiceUnavailableException;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -45,7 +46,7 @@ public class PlatformServiceUnavailableExceptionMapper
implements ExceptionMappe
@Override
public Response toResponse(final
AbstractPlatformServiceUnavailableException exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiGlobalErrorResponse serviceUnavailableExceptionResponse =
ApiGlobalErrorResponse.serviceUnavailable(
exception.getGlobalisationMessageCode(),
exception.getDefaultUserMessage(), exception.getDefaultUserMessageArgs());
return
Response.status(Status.SERVICE_UNAVAILABLE).entity(serviceUnavailableExceptionResponse).type(MediaType.APPLICATION_JSON)
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/RollbackTransactionNotApprovedExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/RollbackTransactionNotApprovedExceptionMapper.java
index 33087afbe..93f8b29d6 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/RollbackTransactionNotApprovedExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/RollbackTransactionNotApprovedExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import
org.apache.fineract.commands.exception.RollbackTransactionNotApprovedException;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -45,7 +46,7 @@ public class RollbackTransactionNotApprovedExceptionMapper
@Override
public Response toResponse(final RollbackTransactionNotApprovedException
exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
return Response.ok().entity(new
Gson().toJson(exception.getResult())).type(MediaType.APPLICATION_JSON).build();
}
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnAuthenticatedUserExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnAuthenticatedUserExceptionMapper.java
index 0f979f01c..2d9b00a25 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnAuthenticatedUserExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnAuthenticatedUserExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import
org.apache.fineract.useradministration.exception.UnAuthenticatedUserException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -42,7 +43,7 @@ public class UnAuthenticatedUserExceptionMapper implements
ExceptionMapper<UnAut
@Override
public Response toResponse(@SuppressWarnings("unused") final
UnAuthenticatedUserException exception) {
// Status code 401 really reads as: "Unauthenticated":
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
return
Response.status(Status.UNAUTHORIZED).entity(ApiGlobalErrorResponse.unAuthenticated()).type(MediaType.APPLICATION_JSON)
.build();
}
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnrecognizedQueryParamExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnrecognizedQueryParamExceptionMapper.java
index e952a74eb..4bb4b21ec 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnrecognizedQueryParamExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnrecognizedQueryParamExceptionMapper.java
@@ -28,6 +28,7 @@ import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import
org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -55,7 +56,7 @@ public class UnrecognizedQueryParamExceptionMapper implements
ExceptionMapper<Un
.append(parameterName) //
.append(" has an unsupported value of: ") //
.append(parameterValue);
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiParameterError error =
ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(),
parameterName, parameterName, parameterValue,
exception.getSupportedParams());
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedCommandExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedCommandExceptionMapper.java
index daaf720ec..387d6b84a 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedCommandExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedCommandExceptionMapper.java
@@ -29,6 +29,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.commands.exception.UnsupportedCommandException;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -53,7 +54,7 @@ public class UnsupportedCommandExceptionMapper implements
ExceptionMapper<Unsupp
if (message != null) {
defaultEnglishMessage.append(" ").append(message);
}
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiParameterError error =
ApiParameterError.parameterError(validationErrorCode.toString(),
defaultEnglishMessage.toString(),
exception.getUnsupportedCommandName(),
exception.getUnsupportedCommandName());
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedParameterExceptionMapper.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedParameterExceptionMapper.java
index 65d515ff9..1309798b6 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedParameterExceptionMapper.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedParameterExceptionMapper.java
@@ -28,6 +28,7 @@ import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import
org.apache.fineract.infrastructure.core.exception.UnsupportedParameterException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -55,7 +56,7 @@ public class UnsupportedParameterExceptionMapper implements
FineractExceptionMap
errors.add(error);
}
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiGlobalErrorResponse invalidParameterError =
ApiGlobalErrorResponse
.badClientRequest("validation.msg.validation.errors.exist",
"Validation errors exist.", errors);
diff --git
a/fineract-investor/src/main/java/org/apache/fineract/investor/exception/exceptionmapper/ExternalAssetOwnerInitiateTransferExceptionMapper.java
b/fineract-investor/src/main/java/org/apache/fineract/investor/exception/exceptionmapper/ExternalAssetOwnerInitiateTransferExceptionMapper.java
index e10fabab2..243ac83c0 100644
---
a/fineract-investor/src/main/java/org/apache/fineract/investor/exception/exceptionmapper/ExternalAssetOwnerInitiateTransferExceptionMapper.java
+++
b/fineract-investor/src/main/java/org/apache/fineract/investor/exception/exceptionmapper/ExternalAssetOwnerInitiateTransferExceptionMapper.java
@@ -24,6 +24,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import
org.apache.fineract.investor.exception.ExternalAssetOwnerInitiateTransferException;
import org.springframework.stereotype.Component;
@@ -36,7 +37,7 @@ public class
ExternalAssetOwnerInitiateTransferExceptionMapper implements Except
public Response toResponse(ExternalAssetOwnerInitiateTransferException
exception) {
final String globalisationMessageCode =
"error.msg.external.asset.owner.initiate";
final String defaultUserMessage = exception.getMessage();
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiParameterError error =
ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LinkedAccountRequiredExceptionMapper.java
b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LinkedAccountRequiredExceptionMapper.java
index 8f24811cf..6af3fd29f 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LinkedAccountRequiredExceptionMapper.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LinkedAccountRequiredExceptionMapper.java
@@ -35,7 +35,7 @@ public class LinkedAccountRequiredExceptionMapper implements
FineractExceptionMa
@Override
public Response toResponse(LinkedAccountRequiredException exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiGlobalErrorResponse notFoundErrorResponse =
ApiGlobalErrorResponse.domainRuleViolation(
exception.getGlobalisationMessageCode(),
exception.getDefaultUserMessage(), exception.getDefaultUserMessageArgs());
// request understood but not carried out due to it violating some
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LoanIdsHardLockedExceptionMapper.java
b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LoanIdsHardLockedExceptionMapper.java
index 81f074358..23188bce1 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LoanIdsHardLockedExceptionMapper.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LoanIdsHardLockedExceptionMapper.java
@@ -36,7 +36,7 @@ public class LoanIdsHardLockedExceptionMapper implements
FineractExceptionMapper
@Override
public Response toResponse(LoanIdsHardLockedException exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
return Response.status(HttpStatus.SC_CONFLICT)
.entity(ApiGlobalErrorResponse.loanIsLocked(exception.getLoanIdFromRequest()).toJson()).type(MediaType.APPLICATION_JSON)
.build();
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiDisbursementDataRequiredExceptionMapper.java
b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiDisbursementDataRequiredExceptionMapper.java
index c8b675306..b598de247 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiDisbursementDataRequiredExceptionMapper.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiDisbursementDataRequiredExceptionMapper.java
@@ -36,7 +36,7 @@ public class MultiDisbursementDataRequiredExceptionMapper
@Override
public Response toResponse(MultiDisbursementDataRequiredException
exception) {
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiGlobalErrorResponse notFoundErrorResponse =
ApiGlobalErrorResponse.domainRuleViolation(
exception.getGlobalisationMessageCode(),
exception.getDefaultUserMessage(), exception.getDefaultUserMessageArgs());
// request understood but not carried out due to it violating some
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/LoanAccountLockCannotBeOverruledExceptionMapper.java
b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/LoanAccountLockCannotBeOverruledExceptionMapper.java
index 3cdfd2e37..9990f6f43 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/LoanAccountLockCannotBeOverruledExceptionMapper.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/LoanAccountLockCannotBeOverruledExceptionMapper.java
@@ -25,6 +25,7 @@ import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import
org.apache.fineract.cob.exceptions.LoanAccountLockCannotBeOverruledException;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.stereotype.Component;
@Provider
@@ -36,7 +37,7 @@ public class LoanAccountLockCannotBeOverruledExceptionMapper
implements Exceptio
public Response toResponse(LoanAccountLockCannotBeOverruledException
exception) {
final String globalisationMessageCode =
"error.msg.invalid.request.body";
final String defaultUserMessage = exception.getMessage();
- log.warn("Exception occurred", exception);
+ log.warn("Exception occurred",
ErrorHandler.findMostSpecificException(exception));
final ApiParameterError error =
ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
diff --git a/fineract-provider/src/main/resources/application.properties
b/fineract-provider/src/main/resources/application.properties
index 81833a3c1..aa3e5f723 100644
--- a/fineract-provider/src/main/resources/application.properties
+++ b/fineract-provider/src/main/resources/application.properties
@@ -322,7 +322,7 @@
resilience4j.retry.instances.executeCommand.max-attempts=${FINERACT_COMMAND_PROC
resilience4j.retry.instances.executeCommand.wait-duration=${FINERACT_COMMAND_PROCESSING_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.executeCommand.enable-exponential-backoff=${FINERACT_COMMAND_PROCESSING_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.executeCommand.exponential-backoff-multiplier=${FINERACT_COMMAND_PROCESSING_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
-resilience4j.retry.instances.executeCommand.retryExceptions=${FINERACT_COMMAND_PROCESSING_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,org.apache.fineract.infrastructure.core.exception.IdempotentCommandProcessUnderProcessingException}
+resilience4j.retry.instances.executeCommand.retryExceptions=${FINERACT_COMMAND_PROCESSING_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException,org.apache.fineract.infrastructure.core.exception.IdempotentCommandProcessUnderProcessingException}
resilience4j.retry.instances.processJobDetailForExecution.max-attempts=${FINERACT_PROCESS_JOB_DETAIL_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.processJobDetailForExecution.wait-duration=${FINERACT_PROCESS_JOB_DETAIL_RETRY_WAIT_DURATION:1s}
@@ -333,10 +333,10 @@
resilience4j.retry.instances.recalculateInterest.max-attempts=${FINERACT_PROCESS
resilience4j.retry.instances.recalculateInterest.wait-duration=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.recalculateInterest.enable-exponential-backoff=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.recalculateInterest.exponential-backoff-multiplier=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
-resilience4j.retry.instances.recalculateInterest.retryExceptions=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException}
+resilience4j.retry.instances.recalculateInterest.retryExceptions=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
resilience4j.retry.instances.postInterest.max-attempts=${FINERACT_PROCESS_POST_INTEREST_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.postInterest.wait-duration=${FINERACT_PROCESS_POST_INTEREST_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.postInterest.enable-exponential-backoff=${FINERACT_PROCESS_POST_INTEREST_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.postInterest.exponential-backoff-multiplier=${FINERACT_PROCESS_POST_INTEREST_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
-resilience4j.retry.instances.postInterest.retryExceptions=${FINERACT_PROCESS_POST_INTEREST_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException}
+resilience4j.retry.instances.postInterest.retryExceptions=${FINERACT_PROCESS_POST_INTEREST_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}