Files
Viper_Wiki/09-exceptions.md
TermiNexus 947c1b35e5 docs(wiki): 改建第 12 章为编译系统,统一 long 宽度口径并补齐章节编号
- 12-project.md 改建为 12-compilation-system.md:介绍编译系统总览、工程配置
  project.vpj 与 viperbuild 元编程;同步 README 与第 17 章的引用
- README.MD:新增「C-LIKE 语法(逐步支持)」小节——自研语法器 includes/ast 将逐步
  支持 C-LIKE 写法,双端写法与语义长期维护,但实际工程仍推荐 ABC-LIKE;流水线章节
  去掉「Python 单文件模式 / project.json」旧措辞,改述工程根来源并补 --src 与 viperbuild
- 02-type-system.md:long / unsigned long 位宽改为平台相关(Windows LLP64=32、
  LP64=64)并补注权威实现;修正 stdint.LONGLONG / ULONGLONG 展开;统一整型 None 判空写法
- 05-classes.md:补 t.Anonymous 废弃告警;07-control-flow.md:for-else 改为已实现措辞
- 15/16/17/18 章重编号为 14/15/16/17,填补 14-oo-refactor 删除后的编号空洞,
  同步各章标题与全仓引用
2026-10-02 22:05:18 +08:00

3.8 KiB

09 - 异常处理

本章待修订(机制与实现存在偏差,见各节标注)

说明:本章讲的是语言层 try/except(错误码 + 错误消息出参)。运行期崩溃 / 按键时打印的调用栈回溯是另一套机制,见 16-traceback.md。

Viper 支持 Python 风格的 try/except/finally 异常处理,采用基于错误码 + 错误消息出参的传播机制(不使用 C++ 风格的零开销异常)。

异常处理机制

编译器自动为可能抛出异常的函数追加 __eh_code_out__(i32*) 与 __eh_msg_out__(i8**) 出参;调用点传入接收缓冲,调用后检查 msg != NULL,按 code 匹配 except。

try / except

try:
    result = risky_operation()
except ValueError:
    serial.puts("ValueError occurred\n")
except OSError:
    serial.puts("OSError occurred\n")
except Exception:
    serial.puts("Unknown error\n")

内置异常类型

Viper 预定义了以下异常类型及其错误码:

异常类型 错误码
ValueError 1
TypeError 2
RuntimeError 3
ZeroDivisionError 4
IndexError 5
KeyError 6
IOError 7
OSError 8
AssertionError 9
Exception 99

自定义异常

class DiskFullError(Exception):
    pass

class ReadOnlyError(DiskFullError):
    pass

自定义异常会自动分配递增的错误码(从 100 开始),并支持继承匹配。

多异常捕获

语法暂不支持(期望)。

try:
    result = operation()
except (ValueError, TypeError):
    serial.puts("Value or Type error\n")

获取异常信息

try:
    result = operation()
except Exception as e:
    serial.puts("Error occurred\n")

try / finally

普通函数中尚未实现(仅协程子集支持纯 try/finally)——期望/后续修正

try:
    result = operation()
finally:
    cleanup()

finally 块无论是否发生异常都会执行。

try / except / finally

普通函数中尚未实现(仅协程子集支持纯 try/finally)——期望/后续修正

try:
    result = operation()
except ValueError:
    handle_value_error()
finally:
    cleanup()

raise 语句

抛出异常

raise ValueError("invalid value")

抛出自定义异常

raise MyCustomError("something went wrong")

重新抛出异常

当前裸 raise 不重新抛出(返回默认值),期望实现重抛当前异常。

raise

StopIteration

StopIteration 有特殊处理,用于迭代器协议:

raise StopIteration

异常处理的编译实现

函数签名变换

可能抛出异常的函数会自动添加错误输出参数:

def risky_operation() -> int:
    if error:
        raise ValueError("bad value")
    return 0

编译后等价于:

int risky_operation(char** __eh_msg_out__, int* __eh_code_out__) {
    if (error) {
        *__eh_code_out__ = 1;  // ValueError code
        *__eh_msg_out__ = "bad value";
        return 0;
    }
    return 0;
}

调用点变换

try:
    result = risky_operation()
except ValueError:
    handle_error()

编译后等价于:

char* __eh_msg = NULL;
int __eh_code = 0;
int result = risky_operation(&__eh_msg, &__eh_code);
if (__eh_msg != NULL) {
    if (__eh_code == 1) {  // ValueError
        handle_error();
    }
}

异常继承匹配

异常匹配支持继承体系。捕获父类异常时,子类异常也会被匹配:

class FileSystemError(Exception):
    pass

class FileNotFoundError(FileSystemError):
    pass

class PermissionError(FileSystemError):
    pass

try:
    operation()
except FileSystemError:
    # 也会捕获 FileNotFoundError 和 PermissionError
    handle_fs_error()