Skip to content

Commit b00502b

Browse files
authored
feat: P4ADEV-4387 handle error code (#355)
1 parent 91b8699 commit b00502b

25 files changed

+101
-63
lines changed

src/main/java/it/gov/pagopa/pu/workflow/event/payments/consumer/PaymentsConsumer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public void accept(PaymentEventDTO paymentEventDTO) {
7373
.transferIndexes(i.getTransfers().stream()
7474
.filter(t ->{
7575
Organization organization = organizationService.getOrganizationByFiscalCode(t.getOrgFiscalCode())
76-
.orElseThrow(() -> new WorkflowNotFoundException("Organization not found with fiscalCode " + t.getOrgFiscalCode()));
76+
.orElseThrow(() -> new WorkflowNotFoundException("[ORGANIZATION_NOT_FOUND] Organization not found with fiscalCode " + t.getOrgFiscalCode()));
7777
return debtPosition.getOrganizationId().equals(organization.getOrganizationId());
7878
})
7979
.map(TransferDTO::getTransferIndex)

src/main/java/it/gov/pagopa/pu/workflow/exception/WorkflowExceptionHandler.java

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import tools.jackson.core.JacksonException;
3232
import tools.jackson.databind.DatabindException;
3333

34+
import java.util.Optional;
3435
import java.util.stream.Collectors;
3536

3637
/**
@@ -41,6 +42,8 @@
4142
@Order(Ordered.HIGHEST_PRECEDENCE)
4243
public class WorkflowExceptionHandler {
4344

45+
private static final String ERROR_MESSAGE_FORMAT = "[%s] %s";
46+
4447
@ExceptionHandler(WorkflowExecutionAlreadyStarted.class)
4548
public ResponseEntity<WorkflowErrorDTO> handleWorkflowExecutionAlreadyStarted(WorkflowExecutionAlreadyStarted ex, HttpServletRequest request) {
4649
return handleException(ex, request, HttpStatus.CONFLICT, WorkflowErrorDTO.CodeEnum.WORKFLOW_CONFLICT);
@@ -78,10 +81,10 @@ public ResponseEntity<WorkflowErrorDTO> handleTooManyAttemptsException(RuntimeEx
7881

7982
@ExceptionHandler({ServletException.class, ErrorResponseException.class})
8083
public ResponseEntity<WorkflowErrorDTO> handleServletException(Exception ex, HttpServletRequest request) {
81-
HttpStatusCode httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
84+
HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
8285
WorkflowErrorDTO.CodeEnum errorCode = WorkflowErrorDTO.CodeEnum.WORKFLOW_GENERIC_ERROR;
8386
if (ex instanceof ErrorResponse errorResponse) {
84-
httpStatus = errorResponse.getStatusCode();
87+
httpStatus = HttpStatus.valueOf((errorResponse.getStatusCode().value()));
8588
if (httpStatus.isSameCodeAs(HttpStatus.NOT_FOUND)) {
8689
errorCode = WorkflowErrorDTO.CodeEnum.WORKFLOW_NOT_FOUND;
8790
} else if (httpStatus.is4xxClientError()) {
@@ -105,17 +108,26 @@ public ResponseEntity<WorkflowErrorDTO> handleRuntimeException(RuntimeException
105108
return handleException(ex, request, HttpStatus.INTERNAL_SERVER_ERROR, WorkflowErrorDTO.CodeEnum.WORKFLOW_GENERIC_ERROR);
106109
}
107110

108-
static ResponseEntity<WorkflowErrorDTO> handleException(Exception ex, HttpServletRequest request, HttpStatusCode httpStatus, WorkflowErrorDTO.CodeEnum errorEnum) {
111+
static ResponseEntity<WorkflowErrorDTO> handleException(Exception ex, HttpServletRequest request, HttpStatus httpStatus, WorkflowErrorDTO.CodeEnum errorEnum) {
109112
logException(ex, request, httpStatus);
110113

111-
String message = buildReturnedMessage(ex);
114+
String message = Optional.of(request.getRequestURI())
115+
.filter(path -> path.contains("/crud/"))
116+
.map(path -> buildCrudErrorMessage(path, httpStatus, ex))
117+
.orElseGet(() -> buildReturnedMessage(ex));
112118

113119
return ResponseEntity
114120
.status(httpStatus)
115121
.contentType(MediaType.APPLICATION_JSON)
116122
.body(new WorkflowErrorDTO(errorEnum, message, Utilities.getTraceId()));
117123
}
118124

125+
private static String buildCrudErrorMessage(String requestPath, HttpStatus httpStatus, Exception ex) {
126+
String entity = requestPath.split("/crud/")[1].split("/")[0].replaceAll("s$", "");
127+
String entityCode = entity.replace("-", "_").toUpperCase();
128+
return String.format(ERROR_MESSAGE_FORMAT, entityCode + "_" + httpStatus.name(), ex.getMessage());
129+
}
130+
119131
private static void logException(Exception ex, HttpServletRequest request, HttpStatusCode httpStatus) {
120132
boolean printStackTrace = httpStatus.is5xxServerError();
121133
Level logLevel = printStackTrace ? Level.ERROR : Level.INFO;
@@ -136,31 +148,35 @@ private static String buildReturnedMessage(Exception ex) {
136148
switch (ex) {
137149
case HttpMessageNotReadableException httpMessageNotReadableException -> {
138150
if (httpMessageNotReadableException.getCause() instanceof DatabindException jsonMappingException) {
139-
return "Cannot parse body. " +
151+
return String.format(ERROR_MESSAGE_FORMAT, WorkflowErrorDTO.CodeEnum.WORKFLOW_BAD_REQUEST.name(),
152+
"Cannot parse body. " +
140153
jsonMappingException.getPath().stream()
141154
.map(JacksonException.Reference::getPropertyName)
142155
.collect(Collectors.joining(".")) +
143-
": " + jsonMappingException.getOriginalMessage();
156+
": " + jsonMappingException.getOriginalMessage());
144157
}
145-
return "Required request body is missing";
158+
return String.format(ERROR_MESSAGE_FORMAT, WorkflowErrorDTO.CodeEnum.WORKFLOW_BAD_REQUEST.name(),
159+
"Required request body is missing");
146160
}
147161
case MethodArgumentNotValidException methodArgumentNotValidException -> {
148-
return "Invalid request content." +
162+
return String.format(ERROR_MESSAGE_FORMAT, WorkflowErrorDTO.CodeEnum.WORKFLOW_BAD_REQUEST.name(),
163+
"Invalid request content." +
149164
methodArgumentNotValidException.getBindingResult()
150165
.getAllErrors().stream()
151166
.map(e -> " " +
152167
(e instanceof FieldError fieldError ? fieldError.getField() : e.getObjectName()) +
153168
": " + e.getDefaultMessage())
154169
.sorted()
155-
.collect(Collectors.joining(";"));
170+
.collect(Collectors.joining(";")));
156171
}
157172
case ConstraintViolationException constraintViolationException -> {
158-
return "Invalid request content." +
173+
return String.format(ERROR_MESSAGE_FORMAT, WorkflowErrorDTO.CodeEnum.WORKFLOW_BAD_REQUEST.name(),
174+
"Invalid request content." +
159175
constraintViolationException.getConstraintViolations()
160176
.stream()
161177
.map(e -> " " + e.getPropertyPath() + ": " + e.getMessage())
162178
.sorted()
163-
.collect(Collectors.joining(";"));
179+
.collect(Collectors.joining(";")));
164180
}
165181
default -> {
166182
return ex.getMessage();

src/main/java/it/gov/pagopa/pu/workflow/service/DataCipherService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ public <T> byte[] encryptObj(T obj) {
3232
try {
3333
return encrypt(jsonMapper.writeValueAsString(obj));
3434
} catch (JacksonException e) {
35-
throw new IllegalStateException("Cannot serialize object as JSON", e);
35+
throw new IllegalStateException("[JSON_SERIALIZATION_ERROR] Cannot serialize object as JSON", e);
3636
}
3737
}
3838

3939
public <T> T decryptObj(byte[] cipherData, Class<T> clazz) {
4040
try {
4141
return jsonMapper.readValue(decrypt(cipherData), clazz);
4242
} catch (JacksonException e) {
43-
throw new IllegalStateException("Cannot deserialize object as JSON", e);
43+
throw new IllegalStateException("[JSON_DESERIALIZATION_ERROR] Cannot deserialize object as JSON", e);
4444
}
4545
}
4646
}

src/main/java/it/gov/pagopa/pu/workflow/service/WorkflowTypeOrgSaveServiceImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public WorkflowTypeOrgSaveServiceImpl(WorkflowTypeRepository workflowTypeReposit
2727
public WorkflowTypeOrg save(WorkflowTypeOrg entity) {
2828
Long workflowTypeId = entity.getWorkflowTypeId();
2929
WorkflowType workflowType = workflowTypeRepository.findById(workflowTypeId)
30-
.orElseThrow(() -> new WorkflowTypeNotFoundException("Cannot find WorkflowType having id " + workflowTypeId));
30+
.orElseThrow(() -> new WorkflowTypeNotFoundException("[WORKFLOW_TYPE_NOT_FOUND] Cannot find WorkflowType having id " + workflowTypeId));
3131

3232
validateWfExecutionConfigType(entity, workflowType, workflowTypeId);
3333

@@ -39,7 +39,7 @@ public WorkflowTypeOrg save(WorkflowTypeOrg entity) {
3939
private static void validateWfExecutionConfigType(WorkflowTypeOrg entity, WorkflowType workflowType, Long workflowTypeId) {
4040
if (!entity.getDefaultExecutionConfig().getClass().equals(workflowType.getDefaultExecutionConfig().getClass())) {
4141
throw new InvalidWfExecutionConfigException(
42-
"Invalid execution config type for workflowTypeId: %d. Expected: %s, Found: %s".formatted(
42+
"[INVALID_EXECUTION_CONFIG_TYPE] Invalid execution config type for workflowTypeId: %d. Expected: %s, Found: %s".formatted(
4343
workflowTypeId,
4444
workflowType.getDefaultExecutionConfig().getClass().getSimpleName(),
4545
entity.getDefaultExecutionConfig().getClass().getSimpleName()));

src/main/java/it/gov/pagopa/pu/workflow/service/temporal/WorkflowCompletionService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,6 @@ public WorkflowStatusDTO waitTerminationStatus(String workflowId, int maxAttempt
6868
} while (attempts <= maxAttempts);
6969

7070
log.info("Workflow {} did not complete after {} retries. No further attempts will be made.", workflowId, maxAttempts);
71-
throw new TooManyAttemptsException("Maximum number of retries reached for workflow " + workflowId);
71+
throw new TooManyAttemptsException("[TOO_MANY_ATTEMPTS] Maximum number of retries reached for workflow " + workflowId);
7272
}
7373
}

src/main/java/it/gov/pagopa/pu/workflow/service/temporal/WorkflowServiceImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,16 @@ public WorkflowStatusDTO getWorkflowStatus(String workflowId) {
8181
} catch (StatusRuntimeException e) {
8282
if(Status.NOT_FOUND.getCode().equals(e.getStatus().getCode())) {
8383
log.error("Workflow with ID {} not found", workflowId);
84-
throw new WorkflowNotFoundException(e.getMessage());
84+
throw new WorkflowNotFoundException("[WORKFLOW_NOT_FOUND] "+e.getMessage());
8585
}
8686
log.error("An error occurred while retrieving the workflow status: {}", e.getMessage());
87-
throw new WorkflowInternalErrorException(e.getMessage());
87+
throw new WorkflowInternalErrorException("[WORKFLOW_INTERNAL_ERROR] "+e.getMessage());
8888
} catch (io.temporal.client.WorkflowNotFoundException e) {
8989
log.error("Workflow with ID {} not found", workflowId);
90-
throw new WorkflowNotFoundException(e.getMessage());
90+
throw new WorkflowNotFoundException("[WORKFLOW_NOT_FOUND] "+e.getMessage());
9191
} catch (TemporalException e) {
9292
log.error("An error occurred while retrieving the workflow status: {}", e.getMessage());
93-
throw new WorkflowInternalErrorException(e.getMessage());
93+
throw new WorkflowInternalErrorException("[WORKFLOW_INTERNAL_ERROR] "+e.getMessage());
9494
}
9595
}
9696

src/main/java/it/gov/pagopa/pu/workflow/service/wf/debtposition/sync/complete/custom/DebtPositionCustomWfSyncService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public WorkflowCreatedDTO invokeWorkflow(DebtPositionDTO debtPositionDTO, Paymen
3030
if (wfExecutionConfig instanceof FineWfExecutionConfig fineWfExecutionConfig) {
3131
return fineClient.synchronizeFineDP(debtPositionDTO, paymentEventRequest, wfExecutionParameters.isMassive(), fineWfExecutionConfig);
3232
} else {
33-
throw new IllegalStateException("WfExecutionConfig not supported: " + wfExecutionConfig.getClass());
33+
throw new IllegalStateException("[INVALID_CONFIG] WfExecutionConfig not supported: " + wfExecutionConfig.getClass());
3434
}
3535
}
3636
}

src/main/java/it/gov/pagopa/pu/workflow/service/wf/debtposition/sync/complete/generic/PagoPASyncInteractionModelRetrieverService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ public PagoPASyncInteractionModelRetrieverService(BrokerService brokerService) {
1717
public PagoPaInteractionModel retrieveInteractionModel(long organizationId, String accessToken){
1818
return brokerService.findByBrokeredOrganizationId(organizationId, accessToken)
1919
.map(Broker::getPagoPaInteractionModel)
20-
.orElseThrow(() -> new IllegalStateException("Cannot find a broker for organization " + organizationId));
20+
.orElseThrow(() -> new IllegalStateException("[BROKER_NOT_FOUND] Cannot find a broker for organization " + organizationId));
2121
}
2222
}

src/main/java/it/gov/pagopa/pu/workflow/service/wf/debtposition/sync/config/WfExecutionConfigHandlerService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ public void persistAndConfigure(DebtPositionDTO debtPositionDTO, WfExecutionPara
7171

7272
public <T extends WfExecutionConfig> T findStoredExecutionConfig(Long debtPositionId, Class<T> wfExecConfigClass) {
7373
WfExecutionConfig config = findWfExecutionConfigById(debtPositionId)
74-
.orElseThrow(() -> new InvalidWfExecutionConfigException("Execution config not found for debtPositionId: " + debtPositionId));
74+
.orElseThrow(() -> new InvalidWfExecutionConfigException("[INVALID_EXECUTION_CONFIG] Execution config not found for debtPositionId: " + debtPositionId));
7575

7676
if (!wfExecConfigClass.isInstance(config)) {
77-
throw new InvalidWfExecutionConfigException(String.format("Invalid execution config type for debtPositionId: %d. Expected: %s, Found: %s",
77+
throw new InvalidWfExecutionConfigException(String.format("[INVALID_EXECUTION_CONFIG] Invalid execution config type for debtPositionId: %d. Expected: %s, Found: %s",
7878
debtPositionId,
7979
wfExecConfigClass.getSimpleName(),
8080
config.getClass().getSimpleName()

src/main/java/it/gov/pagopa/pu/workflow/service/wf/debtposition/sync/config/WfExecutionConfigMergeService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ private WfExecutionConfig clone(WfExecutionConfig wfConfig) {
4141
try {
4242
return objectMapper.readValue(objectMapper.writeValueAsString(wfConfig), wfConfig.getClass());
4343
} catch (JsonProcessingException e) {
44-
throw new IllegalStateException("Cannot clone WfExecutionConfig class " + wfConfig.getClass().getSimpleName(), e);
44+
throw new IllegalStateException("[INVALID_EXECUTION_CONFIG] Cannot clone WfExecutionConfig class " + wfConfig.getClass().getSimpleName(), e);
4545
}
4646
}
4747

@@ -58,7 +58,7 @@ private WfExecutionConfig mergeInner(WfExecutionConfig defaultConfig, WfExecutio
5858
.readValue(objectMapper.writeValueAsString(wfExecutionConfig)),
5959
defaultConfig.getClass());
6060
} catch (IOException e) {
61-
throw new IllegalStateException("Cannot merge WfExecutionConfig from class " + wfExecutionConfig.getClass().getSimpleName() + " to class " + defaultConfig.getClass().getSimpleName(), e);
61+
throw new IllegalStateException("[INVALID_EXECUTION_CONFIG] Cannot merge WfExecutionConfig from class " + wfExecutionConfig.getClass().getSimpleName() + " to class " + defaultConfig.getClass().getSimpleName(), e);
6262
}
6363
}
6464
}

0 commit comments

Comments
 (0)