# 日志 & 错误处理
## 日志
Casbin 内置的`日志`会将日志输出到控制台,如:
~~~log
2017/07/15 19:43:56 [Request: alice, data1, read ---> true]
~~~
日志记录默认启用,您可以通过调用`Enforcer.EnableLog()`或`NewEnforcer()`构造函数中的最后一个参数来切换它。示例:
~~~go
// 在构造方法中禁用日志
e := casbin.NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv", false)
// 在运行时打开日志
e.EnableLog(true)
~~~
## 错误处理
如果您使用 Casbin 时可能会发生 error 或 panic,可能由如下原因造成:
1. model文件 (. file) 中的语法有误。
2. policy文件 (. csv) 中的语法有误。
3. 来adapter的自定义错误信息(譬如连接MySQL失败)。
4. Casbin的bug。
您需要注意以下五个主要函数出现的error或panic:
| 函数 | 异常时表现 | 如果我想要error而不是panic怎么办? |
| --- | --- | --- |
| [NewEnforcer()](https://godoc.org/github.com/casbin/casbin#NewEnforcer) | 造成panic | 使用[NewEnforcerSafe()](https://godoc.org/github.com/casbin/casbin#NewEnforcerSafe)替代 |
| [LoadModel()](https://godoc.org/github.com/casbin/casbin#Enforcer.LoadModel) | 造成panic | 使用[LoadModelSafe()](https://godoc.org/github.com/casbin/casbin#Enforcer.LoadModelSafe)替代 |
| [LoadPolicy()](https://godoc.org/github.com/casbin/casbin#Enforcer.LoadPolicy) | 返回error | 无 |
| [SavePolicy()](https://godoc.org/github.com/casbin/casbin#Enforcer.SavePolicy) | 返回error | 无 |
| [Enforce()](https://godoc.org/github.com/casbin/casbin#Enforcer.Enforce) | 造成panic | 使用[EnforceSafe()](https://godoc.org/github.com/casbin/casbin#Enforcer.EnforceSafe)替代 |
**注:**`NewEnforcer()`内部调用了方法`LoadModel()`和方法`LoadPolicy()`,所以如果您调用了`NewEnforcer()`,就无需再次调用这两个方法。
### 关于为什么不直接返回所有函数的error
作者认为Golang的异常机制对于开发人员来说是非常不友好的,因为它只是一个字符串,并且没有错误的调用堆栈信息。 Panic 可以显示调用堆栈并能与 Golang IDEs 很好的集成。 大多数Casbin用户同为开发者, 通常在第一次编写Casbin有关的model或是policy多少都会犯错(无论最后是造成error还是panic), panic形式的错误可以使他们获益更多。 当然,比起panic另一些开发者更偏向于使用error, 所以我们也提供了`xxxSafe()`方法将可能产生`xxx()`panic的方法转换为error形式抛出。 您可以根据您的个人喜好来选择使用`xxx()`还是`xxxSafe()`。
## Enforcer的启用和禁用
通过调用`Enforcer.EnableEnforce(false)`方法,我们可以禁用Enforcer。 当Enforcer被禁用时,调用`Enforcer.Enforce()`会永远返回`true`。 但是其他操作 (例如添加或删除policy) 不受影响。 以下为一些示例:
~~~go
e := casbin.NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")
// 将会返回false
// 默认情况下enforcer是启用的
e.Enforce("non-authorized-user", "data1", "read")
// 在运行时禁用enforcer
e.EnableEnforce(false)
// 对任何请求都返回true
e.Enforce("non-authorized-user", "data1", "read")
// 打开enforcer
e.EnableEnforce(true)
// 将会返回false
e.Enforce("non-authorized-user", "data1", "read")
~~~