OnError

当发生未处理错误时, 会自动调用指定的函数.

OnError Function , AddRemove

参数

Function

类型: 函数对象

当未处理的错误发生时调用的函数对象. 函数的参数和返回值如下所示.

AddRemove

类型: 整数

如果为空或省略, 则默认为 1(在所有之前注册的函数之后调用该函数). 否则, 指定下列数字之一:

Function

函数应该接受两个参数:

FunctionName(Thrown, Mode)
Thrown

类型: Any

抛出的值, 通常为 Error 对象.

Mode

类型: 字符串

以下字符串之一:

返回值

回调函数可以返回以下值之一(其他值是为将来使用而保留的, 应该避免):

备注

Function 只会被调用来处理通常会导致显示错误消息的错误或异常. 加载时的错误无法调用, 因为在加载脚本完毕之前无法调用 OnError.

Function 在当前线程中被调用, 在线程退出之前(即在调用堆栈展开之前).

Try, Catch, Throw, OnExit

示例

将脚本产生的错误记录到文本文件, 而不是显示给用户.

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"
unixetc