Spring Boot 中处理异常的方法。抛出异常捕获并抛出相同的异常,这是一种不好的做法吗?
Approach to handle exception in Spring Boot. Throw exception catch and throw the same exception, is it a bad practice?
我正在使用 spring 启动,我正在处理异常处理的好方法:
我遇到过与存储库交互以获得产品的情况。但是,如果数据库出现连接问题怎么办,我不会捕获该异常
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);
}
我有一个控制器建议来捕获异常并且 return 一个很好的响应:
@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。有什么想法吗?
您仍然可以在 ControllerAdvice 中捕获它,即使您不抛出它,因此无需尝试捕获该异常而是添加:
@ExceptionHandler({PSQLException.class})
这是针对 Postgres 的,对于其他类型的数据库,您会有不同的异常,然后您也可以处理该消息,并在 ControllerAdvice
中查看其原因
一般来说,捕获异常并在之后立即再次抛出并没有什么奇怪的。例如,您可以捕获它以将其记录在某处,然后将其扔给下一个处理程序以进行实际处理(就像您的情况一样)。
你可以简单地写:
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
你可能会向系统隐藏一个更大的问题。
我正在使用 spring 启动,我正在处理异常处理的好方法:
我遇到过与存储库交互以获得产品的情况。但是,如果数据库出现连接问题怎么办,我不会捕获该异常
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);
}
我有一个控制器建议来捕获异常并且 return 一个很好的响应:
@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。有什么想法吗?
您仍然可以在 ControllerAdvice 中捕获它,即使您不抛出它,因此无需尝试捕获该异常而是添加:
@ExceptionHandler({PSQLException.class})
这是针对 Postgres 的,对于其他类型的数据库,您会有不同的异常,然后您也可以处理该消息,并在 ControllerAdvice
中查看其原因一般来说,捕获异常并在之后立即再次抛出并没有什么奇怪的。例如,您可以捕获它以将其记录在某处,然后将其扔给下一个处理程序以进行实际处理(就像您的情况一样)。
你可以简单地写:
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
你可能会向系统隐藏一个更大的问题。