核心思想:按需捕获#
| 场景 | 处理方式 | 示例 |
|---|---|---|
| 不接受异常,基本不可能异常 | 抛出 | 不做处理,自然抛出 |
| 不接受异常,但有可能异常 | 抛出 | 1. assert condition, reason 2. catch后自定义raise |
| 接受异常 | 捕获 | 正常捕获 选择日志输出 |
代码示例#
异常重试#
需求:执行特定流程抛出异常时,执行指定次数重试
思路:retry变量控制
基本写法:
</>
python
1def process_wp(retry=3):
2 e = None
3 res = None
4 while retry:
5 try:
6 res = might_err_process()
7 except:
8 print(f'retry {retry}...')
9 e = traceback.format_exc()
10 retry -= 1
11 # 按需等待
12 time.sleep(0.1)
13 else:
14 raise Exception(str(e))
15 return restodo:python可写成装饰器
通用场景#
python#
处理其他非Exception类的异常时(如键盘中断)可以使用traceback模块输出调用栈
</>
python
1import traceback
2try:
3 # 可能抛出异常的代码
4 result = 10 / 0 # 触发 ZeroDivisionError
5 with open("missing_file.txt") as f: # 触发 FileNotFoundError
6 print(f.read())
7except ZeroDivisionError:
8 print("除零错误!")
9except FileNotFoundError as e:
10 print(f"文件未找到: {e}")
11except Exception as e: # 捕获其他继承自Exception类的异常
12 print(f"未知错误: {e}")
13except: # 捕获其他非Exception类的异常,如键盘中断,可以使用trackback模块输出调用栈
14 print(traceback.format_exc())
15else:
16 print("无异常时执行")
17finally:
18 print("始终执行的清理代码")
19
20# 输出:
21# 除零错误!
22# 始终执行的清理代码c++#
</>
c++
1#include <iostream>
2#include <stdexcept>
3using namespace std;
4
5int main() {
6 try {
7 // 可能抛出异常的代码
8 int denominator = 0;
9 if (denominator == 0) {
10 throw runtime_error("除零错误!"); // 抛出异常
11 }
12 int result = 10 / denominator;
13 }
14 catch (const runtime_error& e) { // 捕获特定异常
15 cerr << "运行时错误: " << e.what() << endl;
16 }
17 catch (const exception& e) { // 捕获所有标准异常
18 cerr << "标准异常: " << e.what() << endl;
19 }
20 catch (...) { // 捕获所有其他异常
21 cerr << "未知异常!" << endl;
22 }
23 return 0;
24}
25
26// 输出:
27// 运行时错误: 除零错误!
golang#
- panic/recover类似异常捕获
选择使用runtime包输出调用栈
</>
golang
1package main
2
3import (
4 "fmt"
5 "runtime/debug"
6)
7
8func main() {
9 defer func() {
10 if r := recover(); r != nil {
11 fmt.Println("捕获到 panic:", r)
12 fmt.Println("调用栈:")
13 fmt.Println(string(debug.Stack()))
14 }
15 }()
16
17 panic("测试 panic")
18}- 自定义错误值、手动处理
</>
golang
1package main
2
3import (
4 "errors"
5 "fmt"
6)
7
8func divide(a, b int) (int, error) {
9 if b == 0 {
10 return 0, errors.New("除零错误")
11 }
12 return a / b, nil
13}
14
15func main() {
16 // 正常错误处理
17 result, err := divide(10, 0)
18 if err != nil {
19 fmt.Println("错误:", err) // 错误: 除零错误
20 } else {
21 fmt.Println("结果:", result)
22 }
23}