Commits

Anonymous committed d3cc96f

added _cerrors_ attribute for better error control.

Comments (0)

Files changed (3)

doc/source/simobj.rst

 
           your_c_function = _cwrap_your_c_function(your_c_function)
 
+   .. attribute:: _cerrors_
+
+      This is optional.
+      When C function returns non-zero value, RailGun raises error
+      which just tells the value returned (error code).
+      To make the error message readable, or to handle the error
+      better, you may want to use this attribute.
+
+      If C function returns the non-zero value ``error_code``, and it
+      is found ``_cerrors_``, RailGun will raise the error
+      ``_cerrors_[error_code]``.
+
+      Examples::
+
+          class YourSimObject(SimObject):
+
+              _clibname_ = '...'
+              _clibdir_ = '...'
+              _cmembers_ = [...]
+              _cfuncs_ = [...]
+
+              class YourExceptionClass(Exception):
+                  pass
+
+              _cerrors_ = {
+                  # set exception
+                  1: RuntimeError('error code 1 is raised'),
+                  # you can use your own exception class
+                  2: YourExceptionClass('your error message'),
+                  }
+
+      .. versionadded:: 0.1.7
+
 
 
 .. class:: railgun.SimObject

railgun/simobj.py

             else:
                 return
         else:
-            raise RuntimeError('c-function %s() terminates with code %d'
-                               % (cfname, rcode))
+            if rcode in self._cerrors_:
+                raise self._cerrors_[rcode]
+            else:
+                raise RuntimeError('c-function %s() terminates with code %d'
+                                   % (cfname, rcode))
     cfpywrap.func_name = cfdec.fname
     # wrap it if there is wrap function
     wrap_name = '_cwrap_%s' % cfdec.fname
 class SimObject(object):
     __metaclass__ = MetaSimObject
     _calloc_ = True  # if True, use cstyle.CStyle to allocate memory
+    _cerrors_ = {}
 
     def __init__(self, **kwds):
         """

tests/test_cerrors.py

+from nose.tools import assert_raises # , raises, ok_, with_setup
+from railgun import SimObject, relpath
+
+
+class VectCalcBase(SimObject):
+    _cstructname_ = 'VectCalc'
+    _clibname_ = 'vectclac.so'
+    _clibdir_ = relpath('ext/build', __file__)
+
+    _cmembers_ = [
+        'num_i = 10',
+        'int v1[i] = 1',
+        'int v2[i] = 2',
+        'int v3[i]',
+        'int ans',
+        ]
+
+    _cfuncs_ = [
+        "vec_{op | plus, minus, times, divide}()",
+        "subvec_{op | plus, minus, times, divide}(i i1=0, i< i2=num_i)",
+        "fill_{vec | v1, v2, v3}(int s)",
+        "ans subvec_dot(i i1=0, i< i2=num_i)",
+        ]
+
+
+def check_error(vc, exception):
+    vc.v2.fill(1)
+    # no error
+    vc.vec(op='divide')
+    vc.subvec(op='divide')
+    # at least one 0 raises error
+    vc.v2[-1] = 0
+    # error will be raised
+    assert_raises(exception, vc.vec, op='divide')
+    assert_raises(exception, vc.subvec, op='divide')
+
+
+def test_cerros_valueerror():
+
+    class VectCalc(VectCalcBase):
+        _cerrors_ = {
+            1: ValueError('My error message'),
+            100: RuntimeError('This error will not be raised'),
+            }
+
+    check_error(VectCalc(), ValueError)
+
+
+def test_cerros_user_defined():
+
+    class VectCalc(VectCalcBase):
+
+        class UserDefinedError(Exception):
+            pass
+
+        _cerrors_ = {
+            1: UserDefinedError('My error message'),
+            100: RuntimeError('This error will not be raised'),
+            }
+
+    check_error(VectCalc(), VectCalc.UserDefinedError)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.