自定义异常处理程序未按预期抛出异常

问题描述 投票:0回答:1

我的预期输出是:

{
   "message": " Invalid Booking Id ",
  "statusCode": 400
}

我目前的回应是:

{
    "type": "about:blank",
    "title": "Internal Server Error",
    "status": 500,
    "detail": "Failed to write request",
    "instance": "/hotel/booking/1/transaction"
}

这表明completePayment方法中发生了未处理的异常,并且通用错误处理程序正在捕获它,从而导致500内部服务器错误。

“InvalidPaymentException”问题是由于 Spring Boot 应用程序中未处理的异常而引起的。在提供的代码中,当付款模式不是“UPI”或“CARD”时,会引发“InvalidPaymentModeException”。但是,此异常并未按预期被捕获和处理。相反,会调用用于处理意外异常的通用异常处理程序,从而导致 500 内部服务器错误响应。

错误响应DTO

                @NoArgsConstructor
                @AllArgsConstructor
                public class ErrorResponse {

                    private String message;
                    private int statusCode;

                }

例外

                public class InvalidBookingIdException extends RuntimeException {

                    public InvalidBookingIdException (String message){
                        super(message);
                    }
                }

异常处理程序

                @ControllerAdvice

                public class CustomExceptionHandler extends ResponseEntityExceptionHandler {

                    private static final Logger log = LoggerFactory.getLogger(com.example.bookingservice.ExceptionHandler.CustomExceptionHandler.class);


                    @ExceptionHandler(InvalidPaymentModeException.class)
                    public ResponseEntity<com.example.bookingservice.dto.ErrorResponse> handleInvalidPaymentRequest(InvalidPaymentModeException ex, WebRequest request) {
                        log.error("InvalidPaymentModeException caught: " + ex.getMessage(), ex);

                        com.example.bookingservice.dto.ErrorResponse errorResponse = new com.example.bookingservice.dto.ErrorResponse(ex.getMessage(), HttpStatus.BAD_REQUEST.value());
                        return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
                    }
                }

控制器层

                @RestController
                @RequestMapping(value = "/hotel")
                public class BookingController {


                    @Autowired
                    ModelMapper modelMapper;

                    @Autowired
                    BookingService bookingService;

                    @Autowired
                    RestTemplate restTemplate;

                    @PostMapping(value = "/booking/{id}/transaction", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
                    public ResponseEntity<?> completePayment(@PathVariable(name = "id") int id, @RequestBody TransactionRequestDto transactionRequestDto) {
                        try{
                            // Retrieve the booking based on the provided ID
                            Booking requestedBooking = bookingService.getBookingBasedOnId(id);

                            // Ensure that the transactionRequestDto contains the necessary data
                            System.out.println("Payment Request: " + transactionRequestDto.toString());

                            // Check if the payment mode is valid
                            String paymentMode = transactionRequestDto.getPaymentMode();
                            if (!bookingService.isValidPaymentMode(paymentMode)) {
                                throw new InvalidPaymentModeException("Invalid mode of payment");
                            }

                            // Define the URL for the Payment Service
                            String transactionGet_IdUrl = "http://localhost:8082/payment/transaction";

                            // Make the POST request to the Payment Service
                            ResponseEntity<Integer> transactionResponse = restTemplate.postForEntity(transactionGet_IdUrl, transactionRequestDto, Integer.class);

                            if (transactionResponse.getStatusCode() == HttpStatus.CREATED) {
                                int transactionId = transactionResponse.getBody();
                                System.out.println("Transaction ID: " + transactionId);

                                // Update the booking with the transaction ID
                                requestedBooking.setTransactionId(transactionId);
                                bookingService.updateBooking(id, requestedBooking);

                                // Map the updated booking to a response DTO
                                BookingResponseDto bookingResponseDto = modelMapper.map(requestedBooking, BookingResponseDto.class);

                                return new ResponseEntity<>(bookingResponseDto, HttpStatus.CREATED);
                            } else {
                                // Handle the case where the payment transaction was not successful
                                return ResponseEntity.status(transactionResponse.getStatusCode()).build();
                            }

                        } catch (Exception e){
                            com.example.bookingservice.dto.ErrorResponse errorResponseForOtherExceptions = new com.example.bookingservice.dto.ErrorResponse("Internal Server Error", HttpStatus.INTERNAL_SERVER_ERROR.value());
                            return new ResponseEntity(errorResponseForOtherExceptions,HttpStatus.INTERNAL_SERVER_ERROR);
                        }
                    }

                }

控制台

Hibernate: insert into booking (aadhar_number,booked_on,from_date,num_of_rooms,room_numbers,room_price,to_date,transaction_id,booking_id) values (?,?,?,?,?,?,?,?,?)
In CrudRepository ,exiting save
In BookingServiceImpls ,exiting createBooking
In BookingController ,exiting createBooking
In BookingController ,entering completePayment
In BookingServiceImpls ,entering getBookingBasedOnId
In CrudRepository ,entering findById
Hibernate: select b1_0.booking_id,b1_0.aadhar_number,b1_0.booked_on,b1_0.from_date,b1_0.num_of_rooms,b1_0.room_numbers,b1_0.room_price,b1_0.to_date,b1_0.transaction_id from booking b1_0 where b1_0.booking_id=?
In CrudRepository ,exiting findById
In BookingServiceImpls ,exiting getBookingBasedOnId
Payment Request: TransactionRequestDto(paymentMode=other, bookingId=3, upiId=upi details, cardNumber=65757668687)
In BookingServiceImpls ,entering isValidPaymentMode
In BookingServiceImpls ,exiting isValidPaymentMode
In BookingController ,exiting completePayment
spring spring-boot exception controller runtimeexception
1个回答
0
投票

这是因为你的 try/catch 块,

InvalidPaymentModeException
永远不会从你的方法中抛出。

实际上,你有这个:

try {
  throw new InvalidPaymentModeException();
} catch (Exception e) {
  com.example.bookingservice.dto.ErrorResponse errorResponseForOtherExceptions = new com.example.bookingservice.dto.ErrorResponse("Internal Server Error", HttpStatus.INTERNAL_SERVER_ERROR.value());
  return new ResponseEntity(errorResponseForOtherExceptions,HttpStatus.INTERNAL_SERVER_ERROR);
}

因此,您抛出的异常将被捕获,并且永远不会从此方法中抛出。这就是为什么你的建议没有被触发,相反,你得到了

                            return new ResponseEntity(errorResponseForOtherExceptions,HttpStatus.INTERNAL_SERVER_ERROR);

的输出
© www.soinside.com 2019 - 2024. All rights reserved.