在开发过程中,异常处理是保证系统稳定性和提升用户体验的重要环节。根据不同的情况,我们通常将异常分为 业务异常 和 系统异常,并根据不同类型的异常采取不同的处理策略。
1. 业务异常(Business Exception)
定义:
业务异常通常由应用程序的业务逻辑或用户输入错误引发。它们表示业务操作不符合预期或违反了业务规则,通常不影响系统的稳定性。
何时抛出业务异常?
- 用户输入无效,如表单数据格式错误、必填字段缺失等。
- 业务逻辑错误,例如账户余额不足、订单状态不允许操作等。
- 业务规则不匹配,例如用户尝试进行不符合业务规则的操作。
如何抛出业务异常?
在代码中通常会定义自定义的业务异常类(如 BusinessException
),包含错误码和错误信息。
public class BusinessException extends RuntimeException {
private String errorCode;
private String errorMessage;
public BusinessException(String errorCode, String errorMessage) {
super(errorMessage);
this.errorCode = errorCode;
this.errorMessage = errorMessage;
}
// Getter and Setter methods
}
如何处理业务异常?
- 捕获与处理:业务异常通常在业务层(service 层)抛出,并在上层通过统一异常处理机制捕获,返回给用户友好的错误信息。
- 不影响系统运行:业务异常一般不会导致系统崩溃,更多的是指示业务操作的失败。
public void updateAccountBalance(Long accountId, BigDecimal amount) {
if (amount.compareTo(BigDecimal.ZERO) < 0) {
throw new BusinessException("ERR_NEGATIVE_AMOUNT", "Amount cannot be negative");
}
// 业务逻辑处理
}
2. 系统异常(System Exception)
定义:
系统异常通常是由系统资源问题、环境错误或其他不可预见的错误引发的。这些异常一般表示系统发生了错误,可能会影响到系统的稳定性和可用性。
何时抛出系统异常?
- 资源不可用:如数据库连接失败、文件系统异常、网络不可达等。
- 系统级错误:如线程池耗尽、内存溢出、磁盘空间不足等。
- 不可恢复的错误:如外部服务不可用、核心服务出现故障等。
如何抛出系统异常?
系统异常通常使用标准异常类(如 IOException
、SQLException
)或者自定义的系统异常类。
public class SystemException extends RuntimeException {
private String errorCode;
private String errorMessage;
public SystemException(String errorCode, String errorMessage) {
super(errorMessage);
this.errorCode = errorCode;
this.errorMessage = errorMessage;
}
// Getter and Setter methods
}
如何处理系统异常?
- 日志记录和报警:系统异常需要记录详细的日志,并在关键错误发生时发送报警。
- 中断当前操作:通常中止当前操作,并返回给用户系统错误信息。
- 系统恢复机制:通过事务回滚、重试机制等尽量避免系统崩溃。
public void processPayment(Payment payment) {
try {
// 尝试连接支付网关
connectToPaymentGateway(payment);
} catch (IOException e) {
throw new SystemException("ERR_IO_EXCEPTION", "Failed to connect to payment gateway");
}
}
3. 业务异常与系统异常的区别
特性 | 业务异常 | 系统异常 |
---|---|---|
发生原因 | 业务逻辑问题、用户操作错误 | 系统资源问题、环境错误、无法预料的程序异常 |
是否可恢复 | 通常是可恢复的,业务可以重新尝试 | 一般是不可恢复的,可能导致系统或服务中断 |
是否影响系统 | 不影响系统运行,可以继续处理其他请求 | 可能影响系统的稳定性或可用性,严重时会导致系统崩溃 |
抛出位置 | 业务层(Service 层) | 系统底层(DAO 层、框架层、资源连接层等) |
处理方式 | 捕获后返回业务错误信息,进行业务流程回退 | 记录日志,报警,可能中断当前操作,返回系统错误信息 |
4. 异常处理架构设计
为了统一管理业务异常和系统异常,我们需要设计一个异常处理框架,包括全局异常处理器和日志/报警系统。
全局异常处理器
使用 @ControllerAdvice
或全局异常处理类来捕获业务异常和系统异常,并返回统一格式的错误信息给用户。
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex) {
ErrorResponse response = new ErrorResponse(ex.getErrorCode(), ex.getErrorMessage());
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(SystemException.class)
public ResponseEntity<ErrorResponse> handleSystemException(SystemException ex) {
// 记录日志,可能发送报警
ErrorResponse response = new ErrorResponse(ex.getErrorCode(), ex.getErrorMessage());
return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
日志和报警系统
系统异常需要记录详细日志,并根据严重性发送报警通知,帮助及时发现和响应系统错误。
总结
- 业务异常:由业务逻辑错误或用户输入错误引发,不影响系统运行,适合通过友好的错误信息返回给用户。
- 系统异常:由系统资源问题或不可预见的错误引发,可能影响系统的稳定性,需通过日志记录、报警和中断操作来处理。
合理的异常分类与处理可以帮助我们在确保系统稳定的同时,提供良好的用户体验和开发可维护性。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。