# 日志 & 錯誤處理
## 日志
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")
~~~