# try catch 容错语句

相关链接：

- [语句块](blocks.html) 
- [容错调用函数：call](../builtin-function/call.html)  

## 避免使用 try catch 语句

虽然一些编程语言鼓励在代码中到处写满可怕的 try catch 语句，
但这这种编码习惯与风格完全违反了 aardio 的设计理念。

aardio 崇尚极简与实用主义，
不会为了可忽略的、无关紧要的极端情况在代码中去增加大量 try catch 语句。
实际上整个 aardio 标准库使用的  try catch 语句数量接近为 0 ，这不但没有降低代码的可靠性，反而可以减少和避免更多的问题。

这首先是因为 aardio 代码始终在保护运行运态，可以理解为所有的 aardio 代码都是运行在一个 try 语句中，自己再到处去 try 来 try 去通常是多余的。到处写满 try catch ，实际的结果并不会让问题更少，反而会因为代码千万倍地复杂化，制造更多的问题。

aardio 函数通常会利用多返回值检测并处理错误，大多数执行成功会返回非 null 值的函数在执行失败时会返回 `null, 错误信息或错误代码`, 也就是说检测到第一个返回值为 `null` 就可以从第二个返回值获取到错误原因。

示例：

```aardio
//如果出错 result 为 null, err 为错误信息
var result,err = func()

//可以非常简单地通过 result 是否为真进行判断（ null 为 false ）
if( result ){
	print(err);
}

//也可以通过对任何类型对象都容错的直接下标直接检查对象的字段，例如：
if( !result[["image"]] ){
	print(err);	
}

//或者更简单地判断错误信息
if(err){
	print(err);	
}
```

aardio 代码抛出异常通常是为了提醒开发者这是一个错误用法，应当修正代码而非滥用 try catch 语句去兼容这类问题。这是所有 aardio 内置库与标准库的基本设计原则。

## try catch 语句用法

try 语句尝试执行一个语句块，遇到错误则退出 try 语句块而不是中断 aardio 程序。  

如果使用了 catch 语句块就可以在执行代码抛出异常时时捕获错误( catch 语句是可选的 )。
  
示例如下：  

```aardio
import console;

try{
	b = "aaaaaaaaaaaa" *2
	console.log("这里发生错误会中断 try 语句块")
}
catch(e){ //catch 部分可以省略
	console.log( "错误信息：",e )
	//在这里可以调用debug库
	//在栈释放以前调用错误处理 
	//所以可以调用debug库中的函数收集错误相关的信息
}

console.log("上面 try 语句内的错误不会导致退出程序，这里的代码可以继续执行。")
console.pause();
```  

错误信息不一定是一个字符串,传递给 error 的任何信息都会被 catch 捕获。

示例：

```aardio
try{
    error( {a=2;b=3} ) //error 函数显式抛出一个异常
    console.log("错误会中断 try 语句块")
}
catch(e){ 
	//catch 部分可以省略
    console.log( "错误信息：",e.a,e.b) 
}
```  

容错语句是允许多重嵌套的，一个容错语句允许包含另一个容错语句。为了清晰地表示嵌套的层次，建议根据嵌套的层次使用 tab 制表符缩进代码。  

try catch 语句需要遵守以下规则：

1. 在 aardio 中 `try catch` 语句块都是立即执行的匿名函数体。
	- 使用 `return` 语句会跳出 `try catch`  语句块，不会退出包含 `try catch` 的函数。
	- 不能使用 `break` 或 `continue` 语句跳出 `try catch`  语句块。
	- 不能使用 `try catch` 语句块外部的  `...` 参数。可以提前使用 `var args = {...}` 将不定参数转换为数组。
	- 可以使用 `try catch` 语句块外部的 owner 参数。
2. 禁止在 catch 语句中再次调用 error 语句，  
如果需要在抛出异常前插入一些代码，在执行这些插入的代码以后继续抛出异常，那么更好的选择在 global.onError 事件中添加代码。  
层。

