From 898095b82f57298201b030ad0ecf5a669dd24bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Pit=C3=A1k?= <xpitak@fi.muni.cz> Date: Fri, 5 Apr 2024 01:26:30 +0200 Subject: [PATCH] Create artefact with shared implementations, custom exceptions, handling custom exceptions with overriding responses --- infrastructure/pom.xml | 32 ++++++++++++++ .../banking/exception/CustomException.java | 33 +++++++++++++++ .../exception/CustomExceptionHandler.java | 20 +++++++++ .../exception/EntityNotFoundException.java | 42 +++++++++++++++++++ .../pa165/banking/exception/ServerError.java | 40 ++++++++++++++++++ .../exception/UnexpectedValueException.java | 41 ++++++++++++++++++ .../UnsupportedDataTypeException.java | 32 ++++++++++++++ .../pa165/banking/security/AuthService.java | 5 +++ transaction-processor/pom.xml | 11 +++++ .../configuration/BeanRegistry.java | 15 +++++++ .../application/facade/TransactionFacade.java | 6 ++- .../messaging/ProcessProducer.java | 21 ++++++++-- .../service/TransactionService.java | 6 +-- .../domain/messaging/MessageProducer.java | 4 +- .../domain/messaging/ProcessRequest.java | 9 ++++ .../domain/money/CurrencyConverter.java | 3 +- .../domain/process/ProcessFactory.java | 2 +- .../process/handler/DepositHandler.java | 3 +- .../process/handler/ProcessHandler.java | 8 +++- .../handler/ProcessHandlerGateway.java | 3 +- .../process/handler/WithdrawHandler.java | 5 ++- 21 files changed, 320 insertions(+), 21 deletions(-) create mode 100644 infrastructure/pom.xml create mode 100644 infrastructure/src/main/java/cz/muni/pa165/banking/exception/CustomException.java create mode 100644 infrastructure/src/main/java/cz/muni/pa165/banking/exception/CustomExceptionHandler.java create mode 100644 infrastructure/src/main/java/cz/muni/pa165/banking/exception/EntityNotFoundException.java create mode 100644 infrastructure/src/main/java/cz/muni/pa165/banking/exception/ServerError.java create mode 100644 infrastructure/src/main/java/cz/muni/pa165/banking/exception/UnexpectedValueException.java create mode 100644 infrastructure/src/main/java/cz/muni/pa165/banking/exception/UnsupportedDataTypeException.java create mode 100644 infrastructure/src/main/java/cz/muni/pa165/banking/security/AuthService.java create mode 100644 transaction-processor/src/main/java/cz/muni/pa165/banking/application/configuration/BeanRegistry.java diff --git a/infrastructure/pom.xml b/infrastructure/pom.xml new file mode 100644 index 0000000..ed05eb4 --- /dev/null +++ b/infrastructure/pom.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-parent</artifactId> + <version>3.2.4</version> + <relativePath/> + </parent> + + + <groupId>cz.muni.pa165.banking</groupId> + <artifactId>infrastructure</artifactId> + <version>1.0-SNAPSHOT</version> + + <properties> + <maven.compiler.source>21</maven.compiler.source> + <maven.compiler.target>21</maven.compiler.target> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <!-- Only exact dependencies to eliminate transitive dependencies --> + <dependencies> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-web</artifactId> + </dependency> + </dependencies> +</project> \ No newline at end of file diff --git a/infrastructure/src/main/java/cz/muni/pa165/banking/exception/CustomException.java b/infrastructure/src/main/java/cz/muni/pa165/banking/exception/CustomException.java new file mode 100644 index 0000000..aa863e1 --- /dev/null +++ b/infrastructure/src/main/java/cz/muni/pa165/banking/exception/CustomException.java @@ -0,0 +1,33 @@ +package cz.muni.pa165.banking.exception; + +import org.springframework.http.HttpStatus; + +import java.util.LinkedHashMap; +import java.util.Map; + +public abstract class CustomException extends RuntimeException { + + public final Map<String, Object> getBody() { + Map<String, Object> body = new LinkedHashMap<>(); + body.put("status", getStatus()); + body.put("code", getStatus().value()); + body.put("exception", this.getClass().getSimpleName()); + body.put("message", getExceptionMessage()); + body.put("cause", getExceptionCause()); + + if (getDetail() != null) { + body.put("detail", getDetail()); + } + + return body; + } + + public abstract HttpStatus getStatus(); + + abstract String getExceptionMessage(); + + abstract String getExceptionCause(); + + abstract Object getDetail(); + +} diff --git a/infrastructure/src/main/java/cz/muni/pa165/banking/exception/CustomExceptionHandler.java b/infrastructure/src/main/java/cz/muni/pa165/banking/exception/CustomExceptionHandler.java new file mode 100644 index 0000000..7defee0 --- /dev/null +++ b/infrastructure/src/main/java/cz/muni/pa165/banking/exception/CustomExceptionHandler.java @@ -0,0 +1,20 @@ +package cz.muni.pa165.banking.exception; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +/** + * Handles custom exceptions thrown in application. The handler overrides the controller return value, + * evaluating the assigned status code and response body. + * The response body is evaluated as a JSON object, containing defined information such as the status code, + * exception type, message, cause and an optional detail regarding the exception. + */ +public class CustomExceptionHandler { + + @ExceptionHandler(CustomException.class) + public ResponseEntity<Object> handleEntityNotFound(CustomException ex) { + return new ResponseEntity<>(ex.getBody(), ex.getStatus()); + } + +} diff --git a/infrastructure/src/main/java/cz/muni/pa165/banking/exception/EntityNotFoundException.java b/infrastructure/src/main/java/cz/muni/pa165/banking/exception/EntityNotFoundException.java new file mode 100644 index 0000000..a7c55b3 --- /dev/null +++ b/infrastructure/src/main/java/cz/muni/pa165/banking/exception/EntityNotFoundException.java @@ -0,0 +1,42 @@ +package cz.muni.pa165.banking.exception; + +import org.springframework.http.HttpStatus; + +public class EntityNotFoundException extends CustomException { + + private final String cause; + + private final Object detail; + + public EntityNotFoundException(String cause) { + this.cause = cause; + detail = null; + } + + public EntityNotFoundException(String cause, Object detail) { + this.cause = cause; + this.detail = detail; + } + + @Override + public HttpStatus getStatus() { + return HttpStatus.NOT_FOUND; + } + + @Override + String getExceptionMessage() { + return "Entity not present in repository"; + } + + @Override + String getExceptionCause() { + return cause; + } + + @Override + Object getDetail() { + return detail; + } + + +} diff --git a/infrastructure/src/main/java/cz/muni/pa165/banking/exception/ServerError.java b/infrastructure/src/main/java/cz/muni/pa165/banking/exception/ServerError.java new file mode 100644 index 0000000..701242d --- /dev/null +++ b/infrastructure/src/main/java/cz/muni/pa165/banking/exception/ServerError.java @@ -0,0 +1,40 @@ +package cz.muni.pa165.banking.exception; + +import org.springframework.http.HttpStatus; + +public class ServerError extends CustomException { + + private final String cause; + + private final Object detail; + + public ServerError(String cause) { + this.cause = cause; + detail = null; + } + + public ServerError(String cause, Object detail) { + this.cause = cause; + this.detail = detail; + } + @Override + public HttpStatus getStatus() { + return HttpStatus.INTERNAL_SERVER_ERROR; + } + + @Override + String getExceptionMessage() { + return "Internal Server Error"; + } + + @Override + String getExceptionCause() { + return cause; + } + + @Override + Object getDetail() { + return detail; + } + +} diff --git a/infrastructure/src/main/java/cz/muni/pa165/banking/exception/UnexpectedValueException.java b/infrastructure/src/main/java/cz/muni/pa165/banking/exception/UnexpectedValueException.java new file mode 100644 index 0000000..201cfeb --- /dev/null +++ b/infrastructure/src/main/java/cz/muni/pa165/banking/exception/UnexpectedValueException.java @@ -0,0 +1,41 @@ +package cz.muni.pa165.banking.exception; + +import org.springframework.http.HttpStatus; + +public class UnexpectedValueException extends CustomException { + + private final String cause; + + private final Object detail; + + public UnexpectedValueException(String cause, Object detail) { + this.cause = cause; + this.detail = detail; + } + + public UnexpectedValueException(String cause) { + this.cause = cause; + this.detail = null; + } + + @Override + public HttpStatus getStatus() { + return HttpStatus.CONFLICT; + } + + @Override + String getExceptionMessage() { + return "Unexpected value state"; + } + + @Override + String getExceptionCause() { + return cause; + } + + @Override + Object getDetail() { + return detail; + } + +} diff --git a/infrastructure/src/main/java/cz/muni/pa165/banking/exception/UnsupportedDataTypeException.java b/infrastructure/src/main/java/cz/muni/pa165/banking/exception/UnsupportedDataTypeException.java new file mode 100644 index 0000000..68ca401 --- /dev/null +++ b/infrastructure/src/main/java/cz/muni/pa165/banking/exception/UnsupportedDataTypeException.java @@ -0,0 +1,32 @@ +package cz.muni.pa165.banking.exception; + +import org.springframework.http.HttpStatus; + +public class UnsupportedDataTypeException extends CustomException { + + private final String cause; + + public UnsupportedDataTypeException(String cause) { + this.cause = cause; + } + + @Override + public HttpStatus getStatus() { + return HttpStatus.BAD_REQUEST; + } + + @Override + String getExceptionMessage() { + return "Unsupported data type"; + } + + @Override + String getExceptionCause() { + return cause; + } + + @Override + Object getDetail() { + return null; + } +} diff --git a/infrastructure/src/main/java/cz/muni/pa165/banking/security/AuthService.java b/infrastructure/src/main/java/cz/muni/pa165/banking/security/AuthService.java new file mode 100644 index 0000000..2915be0 --- /dev/null +++ b/infrastructure/src/main/java/cz/muni/pa165/banking/security/AuthService.java @@ -0,0 +1,5 @@ +package cz.muni.pa165.banking.security; + +// TODO Milestone2 +public class AuthService { +} diff --git a/transaction-processor/pom.xml b/transaction-processor/pom.xml index b5c4c47..153a12c 100644 --- a/transaction-processor/pom.xml +++ b/transaction-processor/pom.xml @@ -21,6 +21,11 @@ <maven.compiler.target>21</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <!-- External project artifact versions --> + <banking-infrastructure.version>1.0-SNAPSHOT</banking-infrastructure.version> + <banking-openapi.version>1.0-SNAPSHOT</banking-openapi.version> + + <spring.version>3.2.4</spring.version> <openapi-generator.version>6.6.0</openapi-generator.version> <org.mapstruct.version>1.5.5.Final</org.mapstruct.version> @@ -28,6 +33,12 @@ </properties> <dependencies> + <dependency> + <groupId>cz.muni.pa165.banking</groupId> + <artifactId>infrastructure</artifactId> + <version>${banking-infrastructure.version}</version> + </dependency> + <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/configuration/BeanRegistry.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/configuration/BeanRegistry.java new file mode 100644 index 0000000..b9f7585 --- /dev/null +++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/configuration/BeanRegistry.java @@ -0,0 +1,15 @@ +package cz.muni.pa165.banking.application.configuration; + +import cz.muni.pa165.banking.exception.CustomExceptionHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; + +@Component +public class BeanRegistry { + + @Bean + public CustomExceptionHandler exceptionHandler() { + return new CustomExceptionHandler(); + } + +} diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/facade/TransactionFacade.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/facade/TransactionFacade.java index 0d96a02..f92c60d 100644 --- a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/facade/TransactionFacade.java +++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/facade/TransactionFacade.java @@ -4,11 +4,15 @@ import cz.muni.pa165.banking.application.mapper.DtoMapper; import cz.muni.pa165.banking.application.service.TransactionService; import cz.muni.pa165.banking.domain.process.Process; import cz.muni.pa165.banking.domain.transaction.Transaction; +import cz.muni.pa165.banking.exception.EntityNotFoundException; import cz.muni.pa165.banking.transaction.processor.dto.ProcessDto; import cz.muni.pa165.banking.transaction.processor.dto.TransactionDto; +import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; -@Service +import java.util.List; + +@Component public class TransactionFacade { private final TransactionService service; diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/ProcessProducer.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/ProcessProducer.java index b091645..44cdc38 100644 --- a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/ProcessProducer.java +++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/ProcessProducer.java @@ -1,12 +1,14 @@ package cz.muni.pa165.banking.application.messaging; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import cz.muni.pa165.banking.domain.messaging.MessageProducer; import cz.muni.pa165.banking.domain.messaging.ProcessRequest; +import cz.muni.pa165.banking.exception.ServerError; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import java.util.Map; + @Service public class ProcessProducer implements MessageProducer { @@ -24,9 +26,20 @@ public class ProcessProducer implements MessageProducer { @Override - public void send(ProcessRequest data) throws JsonProcessingException { - String dataAsJsonString = mapper.writeValueAsString(data); -// template.convertAndSend(EXCHANGE_NAME, "", data); + public void send(ProcessRequest data) { + String dataAsJsonString; + try { + dataAsJsonString = mapper.writeValueAsString(data); + } catch (Exception e) { + throw new ServerError( + "Unable to map ProcessRequest to String", + Map.of( + "causeLocation", "cz.muni.pa165.banking.application.messaging.ProcessProducer.send", + "invalidObject", data.toString() + ) + ); + } +// template.convertAndSend(EXCHANGE_NAME, "", dataAsJsonString); } } diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/TransactionService.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/TransactionService.java index 3376d51..51810f0 100644 --- a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/TransactionService.java +++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/TransactionService.java @@ -27,11 +27,7 @@ public class TransactionService { @Transactional(rollbackFor = Exception.class) public Process createProcessForTransaction(Transaction newTransaction) { ProcessFactory factory = new ProcessFactory(processTransactionRepository, processRepository); - try { - return factory.create(newTransaction, processProducer); - } catch (Exception e) { - throw new RuntimeException(e.getMessage()); - } + return factory.create(newTransaction, processProducer); } } diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/messaging/MessageProducer.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/messaging/MessageProducer.java index f5f870b..1359e6e 100644 --- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/messaging/MessageProducer.java +++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/messaging/MessageProducer.java @@ -1,9 +1,7 @@ package cz.muni.pa165.banking.domain.messaging; -import com.fasterxml.jackson.core.JsonProcessingException; - public interface MessageProducer { - void send(ProcessRequest data) throws JsonProcessingException; + void send(ProcessRequest data); } diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/messaging/ProcessRequest.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/messaging/ProcessRequest.java index 79bf529..dece456 100644 --- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/messaging/ProcessRequest.java +++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/messaging/ProcessRequest.java @@ -5,4 +5,13 @@ import cz.muni.pa165.banking.domain.transaction.TransactionType; import java.util.UUID; public record ProcessRequest(UUID uuid, TransactionType type) { + + @Override + public String toString() { + return "ProcessRequest{" + + "uuid=" + uuid + + ", type=" + type + + '}'; + } + } diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/money/CurrencyConverter.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/money/CurrencyConverter.java index b78bbba..e3b709e 100644 --- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/money/CurrencyConverter.java +++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/money/CurrencyConverter.java @@ -1,6 +1,7 @@ package cz.muni.pa165.banking.domain.money; import cz.muni.pa165.banking.domain.money.exchange.ExchangeRateService; +import cz.muni.pa165.banking.exception.UnsupportedDataTypeException; import java.math.BigDecimal; import java.util.Currency; @@ -21,7 +22,7 @@ public class CurrencyConverter { */ public BigDecimal convertTo(Currency target, Money amount) { if (!Currency.getAvailableCurrencies().contains(target)) { - throw new RuntimeException("Unsupported target currency"); + throw new UnsupportedDataTypeException("Unsupported target currency"); } BigDecimal rate = BigDecimal.ONE; if (!amount.getCurrency().equals(target)) { diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/ProcessFactory.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/ProcessFactory.java index 09613c5..a30ddd2 100644 --- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/ProcessFactory.java +++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/ProcessFactory.java @@ -19,7 +19,7 @@ public class ProcessFactory { } - public Process create(Transaction transaction, MessageProducer messageProducer) throws Exception { + public Process create(Transaction transaction, MessageProducer messageProducer) { Process newProcess = new Process(); processRepository.save(newProcess); diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/DepositHandler.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/DepositHandler.java index 49ff9b9..10559e6 100644 --- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/DepositHandler.java +++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/DepositHandler.java @@ -6,6 +6,7 @@ import cz.muni.pa165.banking.domain.process.ProcessTransaction; import cz.muni.pa165.banking.domain.process.repository.HandlerMBeanRepository; import cz.muni.pa165.banking.domain.process.repository.ProcessRepository; import cz.muni.pa165.banking.domain.remote.AccountService; +import cz.muni.pa165.banking.exception.EntityNotFoundException; import java.math.BigDecimal; import java.util.Currency; @@ -23,7 +24,7 @@ class DepositHandler extends ProcessHandler { Account account = processTransaction.getSource(); AccountService accountService = beans.accountService(); if (!accountService.isValid(account)) { - throw new RuntimeException( + throw new EntityNotFoundException( String.format("Account with number {%s} does not exist", account.getAccountNumber()) ); } diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandler.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandler.java index 8b61448..51df0c4 100644 --- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandler.java +++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandler.java @@ -6,6 +6,7 @@ import cz.muni.pa165.banking.domain.process.repository.HandlerMBeanRepository; import cz.muni.pa165.banking.domain.process.repository.ProcessRepository; import cz.muni.pa165.banking.domain.process.status.Status; import cz.muni.pa165.banking.domain.process.status.StatusInformation; +import cz.muni.pa165.banking.exception.UnexpectedValueException; import java.time.Instant; import java.util.UUID; @@ -39,10 +40,13 @@ abstract class ProcessHandler { private void validateProcess(Process process) { if (process.getStatus().equals(Status.FAILED)) { - throw new RuntimeException("Process already finalized, ended with failure: " + process.getStatusInformation()); + throw new UnexpectedValueException( + "Process already closed, ended with failure", + "Failure information: " + process.getStatusInformation() + ); } if (process.getStatus().equals(Status.PROCESSED)) { - throw new RuntimeException("Process already finalized"); + throw new UnexpectedValueException("Process already finalized, ended successfully", process.getStatusInformation()); } } diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandlerGateway.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandlerGateway.java index 2cbe773..4b7dd6f 100644 --- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandlerGateway.java +++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandlerGateway.java @@ -3,6 +3,7 @@ package cz.muni.pa165.banking.domain.process.handler; import cz.muni.pa165.banking.domain.process.repository.HandlerMBeanRepository; import cz.muni.pa165.banking.domain.process.repository.ProcessRepository; import cz.muni.pa165.banking.domain.transaction.TransactionType; +import cz.muni.pa165.banking.exception.EntityNotFoundException; import java.util.UUID; @@ -10,7 +11,7 @@ public class ProcessHandlerGateway { public void handle(UUID processUuid, TransactionType type, ProcessRepository repository, HandlerMBeanRepository beans) { if (!repository.idExists(processUuid.toString())) { - throw new RuntimeException(String.format("Process with uuid {%s} not found", processUuid)); + throw new EntityNotFoundException(String.format("Process with uuid {%s} not found", processUuid)); } ProcessHandler handler = switch (type) { diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/WithdrawHandler.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/WithdrawHandler.java index 124edfe..540bab5 100644 --- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/WithdrawHandler.java +++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/WithdrawHandler.java @@ -7,6 +7,7 @@ import cz.muni.pa165.banking.domain.process.ProcessTransaction; import cz.muni.pa165.banking.domain.process.repository.HandlerMBeanRepository; import cz.muni.pa165.banking.domain.process.repository.ProcessRepository; import cz.muni.pa165.banking.domain.remote.AccountService; +import cz.muni.pa165.banking.exception.EntityNotFoundException; import java.math.BigDecimal; import java.util.Currency; @@ -24,14 +25,14 @@ public class WithdrawHandler extends ProcessHandler { Account account = processTransaction.getSource(); AccountService accountService = beans.accountService(); if (!accountService.isValid(account)) { - throw new RuntimeException( + throw new EntityNotFoundException( String.format("Account with number {%s} does not exist", account.getAccountNumber()) ); } Money money = processTransaction.getAmount(); if (!accountService.accountHasSufficientFunds(account, money.getAmount())) { - throw new RuntimeException( + throw new EntityNotFoundException( String.format( "Account with number {%s} does not have sufficient funds for withdrawal of %s %s", account.getAccountNumber(), -- GitLab