0

我正在使用spring boot,并且正在处理一种处理异常的好方法:

我有这种与存储库交互以获取产品的案例。但是如果数据库存在连接问题怎么办,我不会捕捉到那个异常

Product product = productRepository.findById(productId)
                .orElseThrow(() -> new NotFoundException("Could not find a product"));
try {
// Product logic
} catch(Exception e) {
            throw new ProductException(String.format("Error getting product productId=%s. Exception message: %s",
                    productId, e.getMessage()), e);
        }

我有一个控制器建议来捕获异常并返回一个很好的响应:

@ControllerAdvice
public class ExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler({NotFoundException.class})
    public ResponseEntity<Error> handleNotFoundException(HttpServletRequest request, Exception exception) {
    .....
}

我想我可以做这样的事情:

    try {
        Product product = productRepository.findById(productId)
                    .orElseThrow(() -> new NotFoundException("Could not find a product"));
    } catch(NotFoundException e) {
        throw new NotFoundException(e.getMessage())
    } catch(Exception e) {
                throw new ProductException(String.format("Error getting product productId=%s. Exception message: %s",
                        productId, e.getMessage()), e);

这行得通,但看起来很奇怪,因为我两次抛出 NotFoundException。任何想法?

4

2 回答 2

4

一般来说,捕获一个异常并在之后再次抛出它并没有什么奇怪的。例如,您可以捕获它以将其记录在某处,然后将其扔给下一个处理程序进行实际处理(就像您的情况一样)。

你可以简单地写:

catch (NotFoundException e) {
    // Log if needed
    throw e; // <-- no need to build a new one
}

但是,对于后面的部分,捕获泛型Exception通常是一种不好的做法。这个异常可能来自太多的来源,你不能仅仅假设它是因为数据库没有响应。

所以最好的办法是你的函数捕获它知道如何处理的东西,并抛出它不知道如何处理的东西。例如:

public void yourFunction() throws NotFoundException, ProductException {
    //you don't know how to handle NotFoundException and ProductException here, hence you throw them up
    try {
        // your logic
    } catch (SpecificExceptionYouWantToCatch e) {
        //handle specific exception you know how to handle
    } catch (AnotherSpecificException e) {
        //handle other specific exception you know how to handle
    }
    //Let all the other Runtime exceptions flow up to the caller. 
}

如果出现异常,则出现问题。你不能只是包装它并假装它是一个ProductException,所以:

  • 如果您识别出异常并知道如何处理它,那么就这样做(就像您正在做的那样NotFoundException
  • 但是,如果您没有预料到该异常,那么最好让它流动。在某些时候,它可能会被捕获和处理,或者可能只会使程序崩溃。但是你会想知道它,而如果你只是把它包装成一个ProductException你可能会向系统隐藏一个更大的问题。
于 2020-07-20T23:02:59.393 回答
0

您仍然可以在 ControllerAdvice 中捕获它,即使您不抛出它,因此无需尝试捕获该异常,而是添加:

@ExceptionHandler({PSQLException.class})

这适用于 Postgres,对于其他类型的数据库,您将有不同的例外,然后您也可以处理该消息并在 ControllerAdvice 中查看它的原因

于 2020-07-20T23:02:22.600 回答