# 十三、异常处理

## 关于异常

异常一般是指运行期（此处特指Exception类）会发生的导致程序意外中止的问题，是一种对问题的描述后的封装对象。

在过去开发中，通常异常由系统运行时出错抛出，但现在的开发过程中，我们应在程序开发中合理的抛出异常，比如更新一条不存在的实体，或查询一个不存在的数据等等。

## 异常处理几种方式

* 不处理，直接中断程序执行（不推荐）
* 通过 `try` `catch` `finally` 处理（不推荐）
* 全局统一处理，并记录异常信息（推荐）
* 异常注解方式处理（推荐）

## 最佳处理异常方式

Hoa Framework 框架内提供了一种非常人性化的异常处理操作，无需干扰业务代码，又能实现异常处理共享。只需要在可能出现异常的业务方法申明出贴 `[IfException]` 特性即可，然后通过 `Oops.Set(code)` 方法设置异常状态码。如：

```csharp
[IfException(2000, "用户不存在")]
[IfException("SERVER_ERROR", "服务器异常")]
public void Update(DtoModel dto)
{
    var data = _testRepository.Entity.Single(u => u.Id == dto.Id) 
        ?? throw Oops.Set(2000);    // 设置异常状态码
        
    data.Name = dto.Name;
    _testRepository.Update(data);
    
    throw Oops.Set("SERVER_ERROR");    // 设置异常状态码，支持字符串
}
```

通过 `[IfException]` 异常处理方式，可以有效的分离业务代码和异常信息。

这样的做法有很多好处：

* 保持干净的业务代码
* 异常状态码、异常信息统一管理
* 支持多语言配置

### 最佳实践

统一配置错误信息

```csharp
public class OopsCodeMessage
{
    public const string @2000 = "The Member Not Found.";
    public const string @2001 = "The Member Is Lock.";
    public const string @2002 = "The Member Is Expired.";
}
```

使用

```csharp
[IfException(2000, OopsCodeMessage.@2000)]
[IfException(2002, OopsCodeMessage.@2002)]
public void Update(DtoModel dto)
{
    var data = _testRepository.Entity.Single(u => u.Id == dto.Id) 
        ?? throw Oops.Set(2000);    // 设置异常状态码
        
    throw Oops.Set(2002);    // 抛出异常
}
```
