Skip to content

Commit

Permalink
python_exceptions.i: revise logic to use Push/PopErrorHandler instead…
Browse files Browse the repository at this point in the history
… of setting a global error handler
  • Loading branch information
rouault committed Mar 17, 2023
1 parent 281499b commit 11a9559
Showing 1 changed file with 50 additions and 44 deletions.
94 changes: 50 additions & 44 deletions swig/include/python/python_exceptions.i
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
%{
static int bUseExceptions=0;
static void* pPreviousHandlerUserData = NULL;
static CPLErrorHandler pfnPreviousHandler = CPLDefaultErrorHandler;

static void CPL_STDCALL
Expand Down Expand Up @@ -58,14 +59,6 @@ void UseExceptions() {
if( !bUseExceptions )
{
bUseExceptions = 1;
char* pszNewValue = CPLStrdup(CPLSPrintf("%s %s",
MODULE_NAME,
CPLGetConfigOption("__chain_python_error_handlers", "")));
CPLSetConfigOption("__chain_python_error_handlers", pszNewValue);
CPLFree(pszNewValue);
// if the previous logger was custom, we need the user data available
pfnPreviousHandler =
CPLSetErrorHandlerEx( (CPLErrorHandler) PythonBindingErrorHandler, CPLGetErrorHandlerUserData() );
}
}

Expand All @@ -74,26 +67,7 @@ void DontUseExceptions() {
CPLErrorReset();
if( bUseExceptions )
{
const char* pszValue = CPLGetConfigOption("__chain_python_error_handlers", "");
if( strncmp(pszValue, MODULE_NAME, strlen(MODULE_NAME)) != 0 ||
pszValue[strlen(MODULE_NAME)] != ' ')
{
CPLError(CE_Failure, CPLE_NotSupported,
"Cannot call %s.DontUseExceptions() at that point since the "
"stack of error handlers is: %s", MODULE_NAME, pszValue);
return;
}
char* pszNewValue = CPLStrdup(pszValue + strlen(MODULE_NAME) + 1);
if( pszNewValue[0] == ' ' && pszNewValue[1] == '\0' )
{
CPLFree(pszNewValue);
pszNewValue = NULL;
}
CPLSetConfigOption("__chain_python_error_handlers", pszNewValue);
CPLFree(pszNewValue);
bUseExceptions = 0;
// if the previous logger was custom, we need the user data available. Preserve it.
CPLSetErrorHandlerEx( pfnPreviousHandler, CPLGetErrorHandlerUserData());
}
}
%}
Expand Down Expand Up @@ -124,7 +98,6 @@ static void ClearErrorState()

static void StoreLastException() CPL_UNUSED;

// Note: this is also copy&pasted in gdal_array.i
static void StoreLastException()
{
const char* pszLastErrorMessage =
Expand All @@ -139,18 +112,39 @@ static void StoreLastException()
}
}

static void pushErrorHandler()
{
ClearErrorState();
pfnPreviousHandler = CPLGetErrorHandler(&pPreviousHandlerUserData);
if(pfnPreviousHandler == PythonBindingErrorHandler)
{
fprintf(stderr, "BUG: pushErrorHandler(): previous handler is PythonBindingErrorHandler\n");
// to avoid infinite recursion
pfnPreviousHandler = CPLDefaultErrorHandler;
}
CPLPushErrorHandlerEx(PythonBindingErrorHandler, pPreviousHandlerUserData);
}

static void popErrorHandler()
{
CPLPopErrorHandler();
}

%}

%include exception.i

%exception {

if ( bUseExceptions ) {
ClearErrorState();
const int bLocalUseExceptions = bUseExceptions;
if ( bLocalUseExceptions ) {
pushErrorHandler();
}
$action
if ( bLocalUseExceptions ) {
popErrorHandler();
}
%#ifndef SED_HACKS
if ( bUseExceptions ) {
if ( bLocalUseExceptions ) {
CPLErr eclass = CPLGetLastErrorType();
if ( eclass == CE_Failure || eclass == CE_Fatal ) {
SWIG_exception( SWIG_RuntimeError, CPLGetLastErrorMsg() );
Expand All @@ -160,19 +154,23 @@ static void StoreLastException()
}

%feature("except") Open {
if ( bUseExceptions ) {
ClearErrorState();
const int bLocalUseExceptions = bUseExceptions;
if ( bLocalUseExceptions ) {
pushErrorHandler();
}
$action
if ( bLocalUseExceptions ) {
popErrorHandler();
}
%#ifndef SED_HACKS
if( result == NULL && bUseExceptions ) {
if( result == NULL && bLocalUseExceptions ) {
CPLErr eclass = CPLGetLastErrorType();
if ( eclass == CE_Failure || eclass == CE_Fatal ) {
SWIG_exception( SWIG_RuntimeError, CPLGetLastErrorMsg() );
}
}
%#endif
if( result != NULL && bUseExceptions ) {
if( result != NULL && bLocalUseExceptions ) {
StoreLastException();
%#ifdef SED_HACKS
bLocalUseExceptionsCode = FALSE;
Expand All @@ -181,19 +179,23 @@ static void StoreLastException()
}

%feature("except") OpenShared {
if ( bUseExceptions ) {
ClearErrorState();
const int bLocalUseExceptions = bUseExceptions;
if ( bLocalUseExceptions ) {
pushErrorHandler();
}
$action
if ( bLocalUseExceptions ) {
popErrorHandler();
}
%#ifndef SED_HACKS
if( result == NULL && bUseExceptions ) {
if( result == NULL && bLocalUseExceptions ) {
CPLErr eclass = CPLGetLastErrorType();
if ( eclass == CE_Failure || eclass == CE_Fatal ) {
SWIG_exception( SWIG_RuntimeError, CPLGetLastErrorMsg() );
}
}
%#endif
if( result != NULL && bUseExceptions ) {
if( result != NULL && bLocalUseExceptions ) {
StoreLastException();
%#ifdef SED_HACKS
bLocalUseExceptionsCode = FALSE;
Expand All @@ -202,19 +204,23 @@ static void StoreLastException()
}

%feature("except") OpenEx {
if ( bUseExceptions ) {
ClearErrorState();
const int bLocalUseExceptions = bUseExceptions;
if ( bLocalUseExceptions ) {
pushErrorHandler();
}
$action
if ( bLocalUseExceptions ) {
popErrorHandler();
}
%#ifndef SED_HACKS
if( result == NULL && bUseExceptions ) {
if( result == NULL && bLocalUseExceptions ) {
CPLErr eclass = CPLGetLastErrorType();
if ( eclass == CE_Failure || eclass == CE_Fatal ) {
SWIG_exception( SWIG_RuntimeError, CPLGetLastErrorMsg() );
}
}
%#endif
if( result != NULL && bUseExceptions ) {
if( result != NULL && bLocalUseExceptions ) {
StoreLastException();
%#ifdef SED_HACKS
bLocalUseExceptionsCode = FALSE;
Expand Down

0 comments on commit 11a9559

Please sign in to comment.