在开发过程中,异常处理是保证系统稳定性和提升用户体验的重要环节。根据不同的情况,我们通常将异常分为 业务异常系统异常,并根据不同类型的异常采取不同的处理策略。

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)

定义:

系统异常通常是由系统资源问题、环境错误或其他不可预见的错误引发的。这些异常一般表示系统发生了错误,可能会影响到系统的稳定性和可用性。

何时抛出系统异常?

  • 资源不可用:如数据库连接失败、文件系统异常、网络不可达等。
  • 系统级错误:如线程池耗尽、内存溢出、磁盘空间不足等。
  • 不可恢复的错误:如外部服务不可用、核心服务出现故障等。

如何抛出系统异常?

系统异常通常使用标准异常类(如 IOExceptionSQLException)或者自定义的系统异常类。

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);
    }
}

日志和报警系统

系统异常需要记录详细日志,并根据严重性发送报警通知,帮助及时发现和响应系统错误。


总结

  • 业务异常:由业务逻辑错误或用户输入错误引发,不影响系统运行,适合通过友好的错误信息返回给用户。
  • 系统异常:由系统资源问题或不可预见的错误引发,可能影响系统的稳定性,需通过日志记录、报警和中断操作来处理。

合理的异常分类与处理可以帮助我们在确保系统稳定的同时,提供良好的用户体验和开发可维护性。


今夜有点儿凉
40 声望1 粉丝

今夜有点儿凉,乌云遮住了月亮。