Skip to content

L17. 异常处理专项:让程序不死

Vibe Coding 宣言:程序可以失败,但不能崩溃 (Crash)。优雅地失败是一种艺术。

0. 为什么这一课至关重要? (Why It Matters)

  • 用户的耐心是有限的:如果一点“确定”按钮程序就闪退,用户会直接卸载。
  • 深夜的安稳觉:你不想凌晨 3 点被报错电话吵醒吧?让程序自己记录错误,第二天早上再看。
  • Debug 的线索:没有日志的报错,就像没有尸体的谋杀案。

1. 目标 (Goal)

学会使用 Try-Except 捕获异常,并用 Logging 模块记录错误日志,而不是用 print

2. 核心概念/装备/指令 (The Core)

2.1 捕获 (The Net)

  • try: 尝试做可能会错的事。
  • except: 如果错了,怎么办。
  • finally: 不管错没错,最后都要做的事(比如关文件)。

2.2 日志 (The Black Box)

  • Level: DEBUG < INFO < WARNING < ERROR < CRITICAL。
  • Handler: 日志存哪?文件?控制台?邮件?

3. 实战演练 (Action)

Step 1: 别用 print,用 logging

新建 logger.py,配置全局日志。

python
import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    filename='app.log'
)
logger = logging.getLogger(__name__)

Step 2: 捕获异常 (Catch Me If You Can)

修改之前的爬虫代码:

python
from logger import logger

def get_page(url):
    try:
        response = requests.get(url, timeout=5)
        response.raise_for_status() # 如果 404/500 会抛异常
        return response.text
    except requests.Timeout:
        logger.error(f"Timeout connecting to {url}")
        return None
    except requests.RequestException as e:
        logger.error(f"Error fetching {url}: {e}")
        return None
    except Exception as e:
        logger.critical(f"Unknown error: {e}")
        # 发邮件通知管理员!
        return None

Step 3: 让 Claude 帮你加日志

markdown
# Context
我有以下代码 [粘贴代码]。

# Task
请帮我把所有的 `print` 替换为 `logging`
并在所有可能出错的地方(网络请求、文件读写、数据库操作)加上 try-except 块。

4. 常见问题 (FAQ - Vibe Style)

Q: except Exception 是万能的吗? A: 是,但别滥用。 它会捕获所有错误(包括 Ctrl+C)。最好捕获具体的异常(如 ValueError, IOError)。

Q: 日志文件太大怎么办? A: RotatingFileHandler 它会自动把旧日志切分、压缩、删除。只保留最近几天的。

Q: 什么时候用 print? A: 调试的时候。 代码写完后,所有的 print 都应该删掉或换成 logging。

5. 验收标准 (Definition of Done)

  1. 代码中没有 print 语句。
  2. 运行程序,生成了 app.log 文件。
  3. 人为制造一个错误(断网/输错 URL),程序没有闪退,日志里记录了报错信息。

Next Mission: L18. 单元测试与回归:守住你的阵地

基于 Claude Code 构建