当发生未处理错误时, 会自动调用指定的函数.
OnError Function , AddRemove
类型: 函数对象
当未处理的错误发生时调用的函数对象. 函数的参数和返回值如下所示.
类型: 整数
如果为空或省略, 则默认为 1(在所有之前注册的函数之后调用该函数). 否则, 指定下列数字之一:
函数应该接受两个参数:
FunctionName(Thrown, Mode)
类型: Any
抛出的值, 通常为 Error 对象.
类型: 字符串
以下字符串之一:
"Return"
: Thrown 是一个可持续的运行时错误. 如果回调返回 -1, 则线程继续; 否则线程退出."Exit"
: Thrown 是一个不可持续的运行时错误或脚本抛出的一个值. 线程将退出."ExitApp"
: Thrown 是一个关键的运行时错误, 如 DllCall 检测到的损坏. 程序将退出.回调函数可以返回以下值之一(其他值是为将来使用而保留的, 应该避免):
0
, ""
或没有 return
: 允许错误处理正常进行.1
: 抑制默认错误对话框和任何剩余的错误回调.-1
: 同上, 但如果 Mode 为 "Return"
, 则允许继续执行当前线程.Function 只会被调用来处理通常会导致显示错误消息的错误或异常. 加载时的错误无法调用, 因为在加载脚本完毕之前无法调用 OnError.
Function 在当前线程中被调用, 在线程退出之前(即在调用堆栈展开之前).
OnError LogError i := Integer("cause_error") LogError(exception, mode) { FileAppend "Error on line " exception.Line ": " exception.Message "`n" , "errorlog.txt" return true }
使用 OnError 来实现其他错误处理方法. 注意: 当 Try 处于活动状态时, OnError 是无效的.
AccumulateErrors() { local ea := ErrorAccumulator() ea.Start() return ea } class ErrorAccumulator { Errors := [] ; 累计错误数组. _cb := AccumulateError.Bind(this.Errors) Start() => OnError(this._cb, -1) ; 先注册 cb. Stop() => OnError(this._cb, 0) ; 取消注册 cb. Last => this.Errors[-1] ; 最近的错误. Count => this.Errors.Length ; 累计错误的数目. __item[i] => this.Errors[i] ; 索引. __delete() => this.Stop() ; 用于与函数范围绑定. } ; 这是 OnError 回调函数. 'errors' 是通过 Bind() 给定的值. AccumulateError(errors, e, mode) { if mode != "Return" ; 不可继续. return if e.What = "" ; 表达式缺陷或类似的, 不是内置函数. return try { ; 尝试将错误打印到 stdout. FileAppend Format("{1} ({2}) : ({3}) {4}`n", e.File, e.Line, e.What, e.Message), "*" if HasProp(e, "extra") FileAppend " Specifically: " e.Extra "`n", "*" } errors.Push(e) return -1 ; 继续. } RearrangeWindows() { ; 开始在 'err' 中累积错误. local err := AccumulateErrors() ; 做一些可能失败的事情... MonitorGetWorkArea, &left, &top, &right, &bottom width := (right-left)//2, height := bottom-top WinMove left, top, width, height, A_ScriptFullPath WinMove left+width, top, width, height, "AutoHotkey v2 Help" ; 检查是否发生任何错误. if err.Count MsgBox err.Count " error(s); last error at line #" err.Last.Line else MsgBox "No errors" ; 当变量超出作用域时, Stop 会被自动调用, ; 因为只有我们有一个对象的引用. 这将导致 OnError ; 被调用来解除回调. ; err.Stop() } ; 调用抑制和累积错误的测试函数. RearrangeWindows() ; 调用另一个函数来显示恢复正常的错误行为. WinMove 0, 0, 0, 0, "non-existent window"