# Try

守护一个或多个语句不受由 throw 语句抛出的运行时错误和值的影响.

    Try Statement

    Try
    {
        Statements
    }

## 备注

try 语句后常跟着区块 - 括在大括号中的一个或多个语句(统称为函数或表达式). 如果仅需执行单个语句, 那么此语句可以和 try 放在同一行, 也可以在下一行, 并且可以省略大括号. 要指定仅在 try 捕获错误时执行的代码, 请使用一个或多个 catch 语句.

如果使用 try 而没有 catch 或 finally, 那就相当于一个空的 `catch Error`.

Throw 语句或程序在运行遇到错误时会抛出值. 当 try 区块或由其调用的函数抛出值时, 将进行下列操作:

- 如果该区块有相应的 catch 语句, 则继续执行该语句.
- 如果没有匹配的 catch 语句但有 finally 语句, 则执行该语句并在结束后自动再次抛出值.
- 如果没有匹配的 catch 语句或 finally 语句, 值会被自动再次抛出(除非根本没有 catch 或 finally, 如上所述).

最后一个 catch 后面可以选择加上 else. 如果 try 语句完成后没有抛出异常(并且没有通过 return, break 或类似的方式将控制权转移到其他地方), 则会执行 else 语句. 由 else 语句抛出的异常不会被其相关的 try 语句处理, 但可以被一个包围的 try 语句处理. Finally 也可以出现, 但是必须放在 else 之后, 而且总是最后执行.

如果在没有 try 区块执行的情况下引发异常, 则会显示错误消息, 并且当前线程退出.

可以选择将 One True Brace(OTB) 样式与 try 语句一起使用. 例如:

    try {
        ...
    } catch Error as err {
        ...
    } else {
        ...
    } finally {
        ...
    }

## 相关

Throw, Catch, Else, Finally, 区块, OnError

## 示例

演示 try/catch/throw 的基本概念.

    try  ; 尝试执行的代码.
    {
        HelloWorld
        MakeToast
    }
    catch as e  ; 处理由上面区块抛出的首个错误.
    {
        MsgBox "An error was thrown!`nSpecifically: " e.Message
        Exit
    }

    HelloWorld()  ; 总是成功.
    {
        MsgBox "Hello, world!"
    }

    MakeToast()  ; 总是失败.
    {
        ; 立即跳到 try 区块的错误处理程序:
        throw Error(A_ThisFunc " is not implemented, sorry")
    }

演示内置函数的基本错误处理.

    try
    {
        ; 下列语句尝试备份某些指定类型的文件:
        FileCopy A_MyDocuments "\*.txt", "D:\Backup\Text documents"
        FileCopy A_MyDocuments "\*.doc", "D:\Backup\Text documents"
        FileCopy A_MyDocuments "\*.jpg", "D:\Backup\Photos"
    }
    catch
    {
        MsgBox "There was a problem while backing the files up!",, "IconX"
        ExitApp 1
    }
    else
    {
        MsgBox "Backup successful."
        ExitApp 0
    }

演示使用 try/catch 处理 COM 错误. 有关下面使用的 COM 对象的详情, 请参阅 Using the ScriptControl (Microsoft Docs).

    try
    {
        obj := ComObject("ScriptControl")
        obj.ExecuteStatement('MsgBox "This is embedded VBScript"')  ; 这一行会产生一个 Error.
        obj.InvalidMethod() ; 这一行会产生一个 MethodError.
    }
    catch MemberError  ; 包括 MethodError 和 PropertyError.
    {
        MsgBox "We tried to invoke a member that doesn't exist."
    }
    catch as e
    {
        ; 关于 e 对象的更多细节, 请参阅 Error 对象.
        MsgBox("Exception thrown!`n`nwhat: " e.what "`nfile: " e.file
            . "`nline: " e.line "`nmessage: " e.message "`nextra: " e.extra,, 16)
    }

演示嵌套的 try-catch 语句.

    try Example1 ; 单个语句可以和 Try 语句放在同一行.
    catch Number as e
        MsgBox "Example1() threw " e

    Example1()
    {
        try Example2
        catch Number as e
        {
            if (e = 1)
                throw ; 将捕获的值重新抛给调用者.
            else
                MsgBox "Example2() threw " e
        }
    }

    Example2()
    {
        throw Random(1, 2)
    }

dftg