我在 Spring webStart 应用程序上工作...
我有 2 个(可能还有更多)方法来处理多层异常子句,如下所示:
...
try {
employeeService.updateEmployeePartner(employeeId, partner);
LOG.info("partner details updated for partner id {}", employeeId);
result = new ResponseEntity<>(partner.getId(), HttpStatus.OK);
} catch (EmployeePartnerNotFoundException ex) {
LOG.error(ex.getMessage() + " employee id: ", employeeId);
errorResponse = new ErrorResponse("500", ex.getMessage());
} catch (ReadOperationDeniedException ex) {
LOG.error("User doesn't have permissions to update employee's {} details: {}", employeeId, ex.getMessage());
errorResponse = new ErrorResponse("403", "User doesn't have permissions to update employee's details");
} catch (Exception ex) {
LOG.error("something went wrong while updating employee's {} partner details: {}", employeeId, ex.getMessage());
errorResponse = new ErrorResponse("500", "unspecified server error");
} finally {
result = (result != null) ? result : new ResponseEntity<>(errorResponse, HttpStatus.I_AM_A_TEAPOT); // should be INTERNAL_SERVER_ERROR
}
...
除了此更改之外,另一种方法几乎相同:
employeeService.updateEmployeePartner(employeeId, 合作伙伴);
=>
employeeService.createEmployeePartner(employeeId, 合作伙伴);
并捕获该 block 中的 EmployeePartnerAlreadyExistsException 。
现在,为了减少代码重复,我想将所有错误处理代码分组到一个地方(方法),因此我用以下代码替换了上面的代码
...
try {
employeeService.updateEmployeePartner(employeeId, partner);
LOG.info("partner details updated for partner id {}", employeeId);
result = new ResponseEntity<>(partner.getId(), HttpStatus.OK);
} catch (Exception ex) {
errorResponse = processException(ex, employeeId, "update");
} finally {
result = (result != null) ? result : new ResponseEntity<>(errorResponse, HttpStatus.I_AM_A_TEAPOT); // should be INTERNAL_SERVER_ERROR
}
...
private ErrorResponse processException(Exception ex, Long employeeId, String operation) {
ErrorResponse errorResponse;
if (ex.getClass().equals(EmployeePartnerNotFoundException.class) ||
ex.getClass().equals(EmployeePartnerExistsException.class)) {
LOG.error(ex.getMessage() + " employee id: ", employeeId);
errorResponse = new ErrorResponse("500", ex.getMessage());
} else if (ex.getClass().isInstance(ReadOperationDeniedException.class)) {
LOG.error("User doesn't have permissions to " + operation + " employee's {} details: {}", employeeId, ex.getMessage());
errorResponse = new ErrorResponse("403", "User doesn't have permissions to " + operation + " employee's details");
} else { // Exception
LOG.error("something went wrong while trying to " + operation + " employee's {} partner details: {}", employeeId, ex.getMessage());
errorResponse = new ErrorResponse("500", "unspecified server error");
}
return errorResponse;
}
这是一个足够好的方法吗?或者是否有任何模式可以通过将处理外包给单独的方法/类来处理上述场景中的异常?
由于它是一个 Spring 应用程序,我还考虑使用 Spring 异常处理程序,如下所示:
@ExceptionHandler(Exception.class)
,但这只能满足我的部分要求。
最佳答案
将 @ControllerAdvice 与您的自定义 ErrorResponse 和每个处理程序一起使用以处理单独的异常。请参阅Custom error response Spring
示例代码:
@ControllerAdvice
public class GlobalExceptionHandlers {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandlers.class);
/***************** User Defined Exceptions *************************/
@ExceptionHandler({ EmployeePartnerNotFoundException.class })
public ResponseEntity<Object> handleEmployeePartnerNotFoundException(EmployeePartnerNotFoundException ex) {
logger.error("EmployeePartnerNotFoundException : ", ex);
ErrorResponse errorResponse = new ErrorResponse("500", ex.getMessage());
return new ResponseEntity<Object>(errorResponse, new HttpHeaders(), HttpStatus.BAD_REQUEST);
}
// other exception handlers
}
关于Java 在单独的方法中重复处理异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45461207/