Opened 11 years ago

Closed 5 years ago

#5186 closed enhancement (wontfix)

Exceptions raised in python error handlers do not propagate

Reported by: lpinner Owned by: hobu
Priority: normal Milestone: closed_because_of_github_migration
Component: PythonBindings Version: 1.10.0
Severity: normal Keywords: PushErrorHandler
Cc: Even Rouault

Description

GDAL 1.10 on Ubuntu 13.04 and Win 7

Raising an exception within a custom python error handler when set by gdal.PushErrorHandler(py_function) does not work as expected - the exception gets raised in the function but does not propagate back to the main script. Below is an example to demonstrate:

from osgeo import gdal

def gdal_error_handler(err_class, err_no, err_msg):
    print 'About to raise Exception(%s)'%err_msg
    raise Exception('Raising Exception(%s)'%err_msg)

    print 'We will never see this'

if __name__=='__main__':

    gdal.PushErrorHandler(gdal_error_handler)

    try:
        gdal.Error(gdal.CE_Failure,3,'test error message')
    except:
        print 'gdal.CE_Failure raised an exception'
    else:
        print 'gdal.CE_Failure did not raise an exception'

    gdal.PopErrorHandler()

Output:

About to raise Exception(test error message)
gdal.CE_Failure did not raise an exception

Change History (8)

comment:1 by lpinner, 11 years ago

Version: unspecified1.10.0

comment:2 by lpinner, 11 years ago

Cc: Even Rouault added

CC'ing Even as he implemented support for custom error handlers in r25663 (#4993)

comment:3 by lpinner, 11 years ago

And using a class method as the custom handler segfaults python (Ubuntu 13.04 and Win 7). i.e

from osgeo import gdal

class GdalErrorHandler(object):
    def __init__(self,errorlevel=gdal.CE_Failure):
        self.errorlevel=errorlevel

    def handler(self, err_level, err_no, err_msg):
        if err_level>=self.errorlevel:
            print 'About to raise Exception'
            raise Exception('This is the Exception I expect to see')
        else:
            print 'No exception raised'
            return

        print 'This print statement is never reached as expected'

if __name__=='__main__':

    err=GdalErrorHandler()
    gdal.PushErrorHandler(err.handler)

    try:
        gdal.Error(gdal.CE_Failure,1,'I did not expect to see this error')
    except Exception as e:
        print 'gdal.CE_Failure raised an exception'
        print e
    else:
        print 'gdal.CE_Failure did not raise an exception'

    gdal.PopErrorHandler()

comment:4 by Even Rouault, 11 years ago

Type: defectenhancement

The crash was a ref-counting problem that can be workaround by assigning err.handler to a variable before passing it to gdal.PushErrorHandler()

trunk (r26275) and branches/1.10 (25676) "Python bindings: fix ref-counting of callable passed to gdal.PushErrorHandler() that could cause segfaults (#5186)"

As far as the propagation of exceptions from the custom error handler to the main code, I'm not sure if this is doable. Looks like it would be some complicated magic... Re-typing that as an enhancement

comment:5 by lpinner, 11 years ago

Thanks Even. I've added some info about this to the PythonGotchas wiki page.

comment:6 by Jukka Rahkonen, 9 years ago

Can this ticket be closed due to r26275 and r26276 (which I suppose to be the right changeset for branches/1.10)?

comment:7 by lpinner, 9 years ago

@jratike80 changes r26275 and r26276 address an issue raised in#comment:3, but don't address the enhancement request that is the main ticket issue - propagation of exceptions from the custom error handler back to the main code.

Though if you/Even want to close as "wontfix", given Even's comments in comment:4 that's ok.

comment:8 by Even Rouault, 5 years ago

Milestone: closed_because_of_github_migration
Resolution: wontfix
Status: newclosed

This ticket has been automatically closed because Trac is no longer used for GDAL bug tracking, since the project has migrated to GitHub. If you believe this ticket is still valid, you may file it to https://github.com/OSGeo/gdal/issues if it is not already reported there.

Note: See TracTickets for help on using tickets.