| 159 | === Exceptions raised in custom error handlers do not get caught === |
| 160 | If using GDAL 1.10+ the python bindings allow you to specify a python callable as an error handler (#4993). However, these error handlers appear to be called in a separate thread and any exceptions raised do not propagate back to the main thread (#5186). |
| 161 | |
| 162 | So if you want to [http://gis.stackexchange.com/questions/43404/how-to-detect-a-gdal-ogr-warning/68042 catch warnings as well as errors], something like this won't work: |
| 163 | {{{ |
| 164 | ef error_handler(err_level, err_no, err_msg): |
| 165 | |
| 166 | if err_class >= gdal.CE_Warning: |
| 167 | raise RuntimeError(err_level, err_no, err_msg) #this exception does not propagate back to main thread! |
| 168 | |
| 169 | if __name__=='__main__': |
| 170 | |
| 171 | #Test custom error handler |
| 172 | gdal.PushErrorHandler(error_handler) |
| 173 | gdal.Error(gdal.CE_Warning,2,'test warning message') |
| 174 | gdal.PopErrorHandler() |
| 175 | }}} |
| 176 | |
| 177 | But you can do something like this instead: |
| 178 | {{{ |
| 179 | |
| 180 | class GdalErrorHandler(object): |
| 181 | def __init__(self): |
| 182 | self.err_level=gdal.CE_None |
| 183 | self.err_no=0 |
| 184 | self.err_msg='' |
| 185 | |
| 186 | def handler(self, err_level, err_no, err_msg): |
| 187 | self.err_level=err_level |
| 188 | self.err_no=err_no |
| 189 | self.err_msg=err_msg |
| 190 | |
| 191 | if __name__=='__main__': |
| 192 | |
| 193 | err=GdalErrorHandler() |
| 194 | handler=err.handler # Note don't pass class method directly or python segfaults |
| 195 | # due to a reference counting bug |
| 196 | # http://trac.osgeo.org/gdal/ticket/5186#comment:4 |
| 197 | |
| 198 | gdal.PushErrorHandler(handler) |
| 199 | gdal.UseExceptions() #Exceptions will get raised on anything >= gdal.CE_Failure |
| 200 | |
| 201 | try: |
| 202 | gdal.Error(gdal.CE_Warning,1,'Test warning message') |
| 203 | except Exception as e: |
| 204 | print 'Operation raised an exception' |
| 205 | raise |
| 206 | else: |
| 207 | if err.err_level >= gdal.CE_Warning: |
| 208 | print 'Operation raised an warning' |
| 209 | raise RuntimeError(err.err_level, err.err_no, err.err_msg) |
| 210 | finally: |
| 211 | gdal.PopErrorHandler() |
| 212 | }}} |
| 213 | |