MST

星途 面试题库

面试题:Python自定义异常类:复杂场景与最佳实践

在一个分布式系统模拟项目中,你需要设计和实现一套自定义异常类体系。考虑到系统的不同层次(如网络层、数据处理层、业务逻辑层)可能会出现不同类型的异常。例如,网络层可能出现 `NetworkConnectionError`(继承自 `Exception`),数据处理层可能出现 `DataFormatError`(继承自 `ValueError`),业务逻辑层可能出现 `BusinessRuleViolationError`(继承自 `Exception`)。每个异常类需要具备详细的错误码、错误描述以及能够提供有助于定位问题的上下文信息。请详细描述你设计这个异常类体系的思路,并编写代码示例展示如何在不同层次的函数中抛出和处理这些异常,同时阐述如何在日志记录中有效地利用这些异常信息来辅助调试和问题排查。
34.7万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 异常类继承结构
    • 基于不同层次定义基础异常类,如网络层基于 Exception,数据处理层基于 ValueError,业务逻辑层基于 Exception。这样的继承结构能使异常在合适的体系中归类,方便统一处理和区分不同类型异常。
    • 每个异常类添加错误码、错误描述和上下文信息的属性,以便在异常抛出和处理过程中传递详细信息。
  2. 异常抛出与处理
    • 在不同层次的函数中,根据特定的错误情况抛出相应的异常。例如,网络连接失败时抛出 NetworkConnectionError,数据格式不正确时抛出 DataFormatError 等。
    • 在调用这些函数的上层代码中,使用 try - except 语句捕获并处理异常,根据不同异常类型做出相应的处理逻辑。
  3. 日志记录
    • 在捕获异常后,将异常的错误码、错误描述和上下文信息记录到日志中。这样在调试和问题排查时,可以通过日志准确地定位问题所在层次和具体原因。

代码示例

class NetworkConnectionError(Exception):
    def __init__(self, error_code, error_description, context):
        self.error_code = error_code
        self.error_description = error_description
        self.context = context
        super().__init__(f"Error Code: {self.error_code}, Description: {self.error_description}, Context: {self.context}")

class DataFormatError(ValueError):
    def __init__(self, error_code, error_description, context):
        self.error_code = error_code
        self.error_description = error_description
        self.context = context
        super().__init__(f"Error Code: {self.error_code}, Description: {self.error_description}, Context: {self.context}")

class BusinessRuleViolationError(Exception):
    def __init__(self, error_code, error_description, context):
        self.error_code = error_code
        self.error_description = error_description
        self.context = context
        super().__init__(f"Error Code: {self.error_code}, Description: {self.error_description}, Context: {self.context}")

# 网络层函数示例
def network_operation():
    try:
        # 模拟网络连接失败
        raise NetworkConnectionError("N001", "Network connection failed", "Trying to connect to server X")
    except NetworkConnectionError as e:
        print(f"Caught NetworkConnectionError: {e}")

# 数据处理层函数示例
def data_processing_operation():
    try:
        # 模拟数据格式错误
        raise DataFormatError("D001", "Invalid data format", "Received data in wrong format")
    except DataFormatError as e:
        print(f"Caught DataFormatError: {e}")

# 业务逻辑层函数示例
def business_logic_operation():
    try:
        # 模拟业务规则违反
        raise BusinessRuleViolationError("B001", "Business rule violated", "User input does not meet rule Y")
    except BusinessRuleViolationError as e:
        print(f"Caught BusinessRuleViolationError: {e}")


# 调用示例
network_operation()
data_processing_operation()
business_logic_operation()

日志记录利用

在实际应用中,使用日志库(如 logging)来记录异常信息。例如:

import logging

logging.basicConfig(level=logging.ERROR)

def network_operation():
    try:
        # 模拟网络连接失败
        raise NetworkConnectionError("N001", "Network connection failed", "Trying to connect to server X")
    except NetworkConnectionError as e:
        logging.error(f"NetworkConnectionError: Error Code {e.error_code}, Description {e.error_description}, Context {e.context}")

def data_processing_operation():
    try:
        # 模拟数据格式错误
        raise DataFormatError("D001", "Invalid data format", "Received data in wrong format")
    except DataFormatError as e:
        logging.error(f"DataFormatError: Error Code {e.error_code}, Description {e.error_description}, Context {e.context}")

def business_logic_operation():
    try:
        # 模拟业务规则违反
        raise BusinessRuleViolationError("B001", "Business rule violated", "User input does not meet rule Y")
    except BusinessRuleViolationError as e:
        logging.error(f"BusinessRuleViolationError: Error Code {e.error_code}, Description {e.error_description}, Context {e.context}")


# 调用示例
network_operation()
data_processing_operation()
business_logic_operation()

通过这样的日志记录方式,在调试和排查问题时,可以根据日志中的错误码、描述和上下文信息快速定位问题。