错误处理
Alia 语言提供 try、catch 与 throw 关键字处理错误。
1. 基本语法
try-catch 语句
try <Stack tryStack> catch <Key e> <Stack catchStack>
try 块抛出的错误由 catch 捕获,错误值绑定到变量 e,其作用域限于 catch 块。Alia 不含 finally 子句。
throw 语句
throw <Value error>
throw 为内置别名,抛出 ThrownError 信号,实参 可为任意值;经 catch 捕获时原样绑定。无 try 包裹时抛出会终止程序。
2. 基本用法
抛出错误
throw new Error ['发生错误']
throw new Error ['发生错误', 'CustomError']
捕获错误
try {
print '尝试执行'
throw new Error ['发生错误']
print '这行不会执行'
} catch e {
print '捕获到错误: ' .. e
}
3. 错误类型
Error 是内置错误类,构造形式为 new Error ['message', 'name', 'cause'],实参按位置传入:
message:错误描述,默认''name:错误名称,默认'Error'cause:原始原因,默认Nullstack:堆栈信息,取自cause,无cause时为Null
实例方法:
toString/valueOf:字符串表示 / 消息内容toDescription/toColoredDescription:描述文本 / 染色描述toCode/toColoredCode:代码表示 / 染色代码表示
const error = new Error ['错误信息', 'CustomError']
print typeOf error ~ 输出 'Error'
print error.message ~ 输出 '错误信息'
print error.name ~ 输出 'CustomError'
typeOf 对 Error 实例返回 'Error';区分自定义错误应使用 error.name。
4. 示例代码
4.1 基本错误处理
~ 基本错误处理
try {
print '开始执行'
const result = 10 / 0
print '结果: ' .. result
} catch e {
print '捕获到错误: ' .. e
}
print '继续执行'
4.2 自定义错误
~ 自定义错误:以 name 区分错误种类
try {
print '开始执行'
throw new Error ['自定义错误', 'CustomError']
} catch e {
print '错误信息: ' .. e.message
print '错误名称: ' .. e.name
}
4.3 嵌套错误处理
~ 嵌套错误处理
try {
print '外层 try 开始'
try {
print '内层 try 开始'
throw new Error ['内层错误']
} catch innerError {
print '捕获内层错误: ' .. innerError
throw new Error ['外层错 误']
}
} catch outerError {
print '捕获外层错误: ' .. outerError
}
4.4 错误处理与函数
~ 错误处理与函数
alias divide <Number a> <Number b> -> Number {
if b == 0 {
throw new Error ['除数不能为零', 'DivisionByZero']
}
return a / b
}
try {
const result = call divide [10, 0]
print '结果: ' .. result
} catch e {
print '错误: ' .. e
}
try {
const result = call divide [10, 2]
print '结果: ' .. result
} catch e {
print '错误: ' .. e
}
5. 错误处理最佳实践
5.1 使用 name 区分错误种类
alias validateUser <Object user> -> Boolean {
if user.name == '' {
throw new Error ['用户名不能为空', 'ValidationError']
}
if user.email == '' {
throw new Error ['邮箱不能为空', 'ValidationError']
}
return true
}
try {
const user = *[ name: '', email: 'user@example.com' ]
validateUser user
} catch e {
if e.name == 'ValidationError' {
print '验证错误: ' .. e.message
} else {
print '未知错误: ' .. e
}
}
5.2 错误传播
在函数中捕获错误并重新抛出,添加更多上下文信息:
alias readFile <String path> -> {
try {
~ 尝试读取文件
throw new Error ['文件不存在', 'FileError']
} catch e {
throw new Error ['读取文件失败: ' .. e.message .. ' (路径: ' .. path .. ')', 'ReadError']
}
}
try {
readFile 'nonexistent.txt'
} catch e {
print '错误: ' .. e.message
}
5.3 错误恢复
在捕获错误后进行恢复,继续执行:
alias getUser <Number id> -> Object {
try {
~ 尝试从数据库获取用户
throw new Error ['用户不存在', 'NotFound']
} catch e {
~ 返回默认用户
return *[ id: id, name: '未知用户' ]
}
}
const user = getUser 999
print '用户: ' .. user.name
6. 与其他语言的比较
与 JavaScript 比较
// JavaScript
try {
throw new Error('错误信息');
} catch e {
console.log('捕获到错误:', e.message);
}
~ Alia
try {
throw new Error ['错误信息']
} catch e {
print '捕获到错误: ' .. e
}
与 Python 比较
# Python
try:
raise Exception('错误信息')
except Exception as e:
print('捕获到错误:', str(e))
~ Alia
try {
throw new Error ['错误信息']
} catch e {
print '捕获到错误: ' .. e
}
7. 错误诊断系统
Alia 实现了结构化的错误诊断系统,为解析、类型检查、运行与编译阶段提供统一的诊断输出。
7.1 诊断输出格式
每条诊断以圆角矩形框输出(非 TTY 时为纯文本行),包含以下字段:
- 类型:
Error/Warn,框体颜色分别为红色 / 黄色。 - 标题:顶部框线显示
Error: <错因>/Warn: <错因>。 - 直接位置:
At <文件相对位置> line:column:(标签随语言环境显示)。 - 错误代码:带背景与行号的代码行,错误位置下方标记波浪线。
- 错误类型:
Type: <大类>:<具体代码>,如Type: TypeError:Mismatch。 - 错误原因:
Reason: 对应原因描述。 - 修复方法:
Fix: 修复建议描述。 - 修复后代码:与错误代码格式相同,用绿色标记添加位置。
- 引用链:
From: 上一次调用位置(如有)。
7.2 错误类型代码
错误类型代码由 <大类>:<具体代码> 组成,大类包括:
ParseError:解析错误TypeError:类型错误RuntimeError:运行时错误CompilerError:编译错误FFIError:FFI 错误