Repository: casbin/casbin
Pull request #185 (2018-12-14 15:50:21)

Add more safe functions and test code.
Fix the issues #181


Patch:
diff --git a/README.md b/README.md
index d398a9a..a3cd2eb 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@ Casbin
 [![Release](https://img.shields.io/github/release/casbin/casbin.svg)](https://github.com/casbin/casbin/releases/latest)
 [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/casbin/lobby)
 [![Patreon](https://img.shields.io/badge/patreon-donate-yellow.svg)](http://www.patreon.com/yangluo)
+[![Sourcegraph Badge](https://sourcegraph.com/github.com/casbin/casbin/-/badge.svg)](https://sourcegraph.com/github.com/casbin/casbin?badge)
 
 **News**: still worry about how to write the correct Casbin policy? ``Casbin online editor`` is coming to help! Try it at: http://casbin.org/editor/
 
diff --git a/enforcer_safe.go b/enforcer_safe.go
index 1cb358f..adeedf6 100644
--- a/enforcer_safe.go
+++ b/enforcer_safe.go
@@ -100,3 +100,101 @@ func (e *Enforcer) RemoveFilteredPolicySafe(fieldIndex int, fieldValues ...strin
 	err = nil
 	return
 }
+
+// AddGroupingPolicySafe calls AddGroupingPolicy in a safe way, returns error instead of causing panic.
+func (e *Enforcer) AddGroupingPolicySafe(params ...interface{}) (result bool, err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("%v", r)
+			result = false
+		}
+	}()
+
+	result = e.AddGroupingPolicy(params...)
+	err = nil
+	return
+}
+
+// AddNamedGroupingPolicySafe calls AddNamedGroupingPolicy in a safe way, returns error instead of causing panic.
+func (e *Enforcer) AddNamedGroupingPolicySafe(ptype string, params ...interface{}) (result bool, err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("%v", r)
+			result = false
+		}
+	}()
+
+	result = e.AddNamedGroupingPolicy(ptype, params...)
+	err = nil
+	return
+}
+
+// AddNamedPolicySafe calls AddNamedPolicy in a safe way, returns error instead of causing panic.
+func (e *Enforcer) AddNamedPolicySafe(ptype string, params ...interface{}) (result bool, err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("%v", r)
+			result = false
+		}
+	}()
+
+	result = e.AddNamedPolicy(ptype, params...)
+	err = nil
+	return
+}
+
+// RemoveGroupingPolicySafe calls RemoveGroupingPolicy in a safe way, returns error instead of causing panic.
+func (e *Enforcer) RemoveGroupingPolicySafe(params ...interface{}) (result bool, err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("%v", r)
+			result = false
+		}
+	}()
+
+	result = e.RemoveGroupingPolicy(params...)
+	err = nil
+	return
+}
+
+// RemoveFilteredGroupingPolicySafe calls RemoveFilteredGroupingPolicy in a safe way, returns error instead of causing panic.
+func (e *Enforcer) RemoveFilteredGroupingPolicySafe(fieldIndex int, fieldValues ...string) (result bool, err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("%v", r)
+			result = false
+		}
+	}()
+
+	result = e.RemoveFilteredGroupingPolicy(fieldIndex, fieldValues...)
+	err = nil
+	return
+}
+
+// RemoveNamedGroupingPolicySafe calls RemoveNamedGroupingPolicy in a safe way, returns error instead of causing panic.
+func (e *Enforcer) RemoveNamedGroupingPolicySafe(ptype string, params ...interface{}) (result bool, err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("%v", r)
+			result = false
+		}
+	}()
+
+	result = e.RemoveNamedGroupingPolicy(ptype, params...)
+	err = nil
+	return
+}
+
+// RemoveFilteredNamedGroupingPolicySafe calls RemoveFilteredNamedGroupingPolicy in a safe way, returns error instead of causing panic.
+func (e *Enforcer) RemoveFilteredNamedGroupingPolicySafe(ptype string, fieldIndex int, fieldValues ...string) (result bool, err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("%v", r)
+			result = false
+		}
+	}()
+
+	result = e.RemoveFilteredNamedGroupingPolicy(ptype, fieldIndex, fieldValues...)
+	err = nil
+	return
+}


Test patch:
diff --git a/error_test.go b/error_test.go
index 2be91ab..a4626e2 100644
--- a/error_test.go
+++ b/error_test.go
@@ -151,4 +151,67 @@ func TestMockAdapterErrors(t *testing.T) {
 		t.Log("Test on error: ")
 		t.Log(err3.Error())
 	}
+
+	_, err4 := e.AddGroupingPolicySafe("bob", "admin2")
+
+	if err4 == nil {
+		t.Errorf("Should be an error here.")
+	} else {
+		t.Log("Test on error: ")
+		t.Log(err4.Error())
+	}
+
+	_, err5 := e.AddNamedGroupingPolicySafe("g", []string{"eve", "admin2", "domain1"})
+
+	if err5 == nil {
+		t.Errorf("Should be an error here.")
+	} else {
+		t.Log("Test on error: ")
+		t.Log(err5.Error())
+	}
+
+	_, err6 := e.AddNamedPolicySafe("p", []string{"admin2", "domain2", "data2", "write"})
+
+	if err6 == nil {
+		t.Errorf("Should be an error here.")
+	} else {
+		t.Log("Test on error: ")
+		t.Log(err6.Error())
+	}
+
+	_, err7 := e.RemoveGroupingPolicySafe("bob", "admin2")
+
+	if err7 == nil {
+		t.Errorf("Should be an error here.")
+	} else {
+		t.Log("Test on error: ")
+		t.Log(err7.Error())
+	}
+
+	_, err8 := e.RemoveFilteredGroupingPolicySafe(0, "bob")
+
+	if err8 == nil {
+		t.Errorf("Should be an error here.")
+	} else {
+		t.Log("Test on error: ")
+		t.Log(err8.Error())
+	}
+
+	_, err9 := e.RemoveNamedGroupingPolicySafe("g", []string{"alice", "admin", "domain1"})
+
+	if err9 == nil {
+		t.Errorf("Should be an error here.")
+	} else {
+		t.Log("Test on error: ")
+		t.Log(err9.Error())
+	}
+
+	_, err10 := e.RemoveFilteredNamedGroupingPolicySafe("g", 0, "eve")
+
+	if err10 == nil {
+		t.Errorf("Should be an error here.")
+	} else {
+		t.Log("Test on error: ")
+		t.Log(err10.Error())
+	}
 }