错误处理
func 会区分系统错误、运行时错误和 runtime-print 错误。局部命令 catch 会先于全局处理器运行。
错误类型
| 类型 | 何时出现 | 行为 |
|---|---|---|
F_SYSTEM | 无效命令定义、重复注册、缺失处理器或无效注入配置。 | 立即抛出。系统错误不会传递给用户错误处理器。 |
F_RUNTIME | 选中的命令处理器、catch 方法或全局错误处理器抛出错误。 | 先传递给局部 catch,再传递给全局错误处理器。没有处理器时会直接抛出。 |
F_RUNTIME_PRINT | 输入错误,例如解析失败、未知选项、多个处理器标志同时命中或校验失败。 | 传递给处理器,并默认打印到 stderr,除非调用 preventDefaultPrint()。 |
系统错误
系统错误描述无效框架配置:重复命令名、重复选项 token、缺失处理器、不支持的数组类型、无效装饰器目标或缺失 provider。它们应该在开发阶段修复,不会传递给
@Catch 或 @CatchAll。
单命令 Catch
@Catch() 会在命令类上注册一个方法。它会在任何全局处理器运行前,捕获该命令产生的非系统错误。
import { Catch, Command, Exception, FuncException, Handler } from 'func'
@Command({ name: 'publish' })
export class PublishCommand {
@Catch()
onError(@Exception() exception: FuncException) {
console.error(`publish failed: ${exception.message}`)
exception.preventDefaultPrint()
}
@Handler()
run() {
throw new Error('missing package')
}
}全局错误处理器
@CatchAll() 注册全局错误处理器类。@CommandError() 是 @CatchAll() 的别名。全局处理器需要和应用其他命令一起注册到同一个命令列表中。
import { CatchAll, Exception, FuncException } from 'func'
@CatchAll()
export class ErrorHandler {
constructor(@Exception() exception: FuncException) {
if (exception.level === 'runtime-print') {
console.error(`Invalid input: ${exception.message}`)
exception.preventDefaultPrint()
return
}
console.error(exception.message)
}
}import { FuncModule } from 'func'
import { PublishCommand } from './commands/publish'
import { ErrorHandler } from './error-handler'
@FuncModule({
commands: [PublishCommand, ErrorHandler],
})
export class AppModule {}Runtime-print 错误
Runtime-print 错误默认会打印到 stderr。如果你的处理器已经打印了消息,可以调用 preventDefaultPrint()。
import { F_RUNTIME_PRINT, createRuntimePrintError, errorTypes } from 'func'
throw createRuntimePrintError(
F_RUNTIME_PRINT.VALIDATION,
errorTypes.INPUT,
'Token is required.',
{ option: 'token' },
)