@@ -3,7 +3,8 @@ from enum import IntEnum
3
3
4
4
from pyogrio._ogr cimport (
5
5
CE_None, CE_Debug, CE_Warning, CE_Failure, CE_Fatal, CPLErrorReset,
6
- CPLGetLastErrorType, CPLGetLastErrorNo, CPLGetLastErrorMsg, OGRErr)
6
+ CPLGetLastErrorType, CPLGetLastErrorNo, CPLGetLastErrorMsg, OGRErr,
7
+ CPLErr, CPLErrorHandler, CPLDefaultErrorHandler, CPLPushErrorHandler)
7
8
8
9
9
10
# CPL Error types as an enum.
@@ -207,3 +208,31 @@ cdef int exc_wrap_ogrerr(int err) except -1:
207
208
raise CPLE_BaseError(3 , err, f" OGR Error code {err}" )
208
209
209
210
return err
211
+
212
+
213
+ cdef void error_handler(CPLErr err_class, int err_no, const char * err_msg) nogil:
214
+ """ Custom CPL error handler to match the Python behaviour.
215
+
216
+ Generally we want to suppress error printing to stderr (behaviour of the
217
+ default GDAL error handler) because we already raise a Python exception
218
+ that includes the error message.
219
+ """
220
+ if err_class == CE_Fatal:
221
+ # If the error class is CE_Fatal, we want to have a message issued
222
+ # because the CPL support code does an abort() before any exception
223
+ # can be generated
224
+ CPLDefaultErrorHandler(err_class, err_no, err_msg)
225
+ return
226
+
227
+ elif err_class == CE_Failure:
228
+ # For Failures, do nothing as those are explicitly caught
229
+ # with error return codes and translated into Python exceptions
230
+ return
231
+
232
+ # Fall back to the default handler for non-failure messages since
233
+ # they won't be translated into exceptions.
234
+ CPLDefaultErrorHandler(err_class, err_no, err_msg)
235
+
236
+
237
+ def _register_error_handler ():
238
+ CPLPushErrorHandler(< CPLErrorHandler> error_handler)
0 commit comments