[GRASS-dev] Re: [GRASS GIS] #1646: GRASS ctypes exception handling

GRASS GIS trac at osgeo.org
Thu Apr 26 20:23:46 EDT 2012

#1646: GRASS ctypes exception handling
 Reporter:  huhabla                                  |       Owner:  grass-dev@…              
     Type:  enhancement                              |      Status:  new                      
 Priority:  normal                                   |   Milestone:  7.0.0                    
Component:  Python ctypes                            |     Version:  svn-trunk                
 Keywords:  setjmp, longjmp, Exception, gently exit  |    Platform:  All                      
      Cpu:  All                                      |  

Comment(by huhabla):

 Replying to [comment:2 glynn]:
 > Replying to [comment:1 glynn]:
 > > If you only need coarse-grained fatal-error handling (e.g. calling
 exit handlers),
 > And, in fact, that's all that should be attempted. Fine-grained error
 handling is largely pointless given that you cannot safely call GRASS
 library functions once a fatal error has been triggered (library functions
 are not required to ensure that internal data structures are in a
 consistent state before generating a fatal error).

 Ok, i will try to set Python error handler to clean up in the modules and
 python libraries. I still struggle with the void pointer handling and
 Python object casting. A simple example:

 import grass.lib.gis as gis
 import grass.lib.raster as raster
 from ctypes import *

 class FatalErrorException(Exception):

 def error_routine(message, flag):
     raise FatalErrorException(message)

 def cleanup_handler(name):
     print "Removing %s"%(name)

 ERROR_ROUTINE = CFUNCTYPE(c_int, c_char_p, c_int)(error_routine)
 CLEANUP_HANDLER = CFUNCTYPE(c_void_p, c_void_p)(cleanup_handler)

 def set_raise_on_library_error_routine(raise_exp = True):
     if raise_exp:

 def main():

     name = "elevation_not_exists"
     mapset = "PERMANENT"

     gis.G_add_error_handler(CLEANUP_HANDLER, "%s@%s"%(name, mapset))
     fd = raster.Rast_open_old(name, mapset)

 if __name__ == "__main__":

 Running this module will result in:

 GRASS 7.0.svn (Test):~/src > python test.py
 Traceback (most recent call last):
   File "_ctypes/callbacks.c", line 313, in 'calling callback function'
   File "test.py", line 9, in error_routine
     raise FatalErrorException(message)
 __main__.FatalErrorException: Raster map <elevation_not_exists at PERMANENT>
 not found
 Removing 10575748

 Raising a FatalErrorException is a bit pointless, but it works as
 expected. The main problem is that i have no clue how to cast the Python
 string from void pointer in the clean up handler, or how to cast any other
 Python object i need to clean up?

Ticket URL: <http://trac.osgeo.org/grass/ticket/1646#comment:3>
GRASS GIS <http://grass.osgeo.org>

More information about the grass-dev mailing list