Harmonize error handling
Python reports errors by returning an error condition (ex. NULL pointer or -1 integer) and providing a global error state with all the details, such error state needs to be cleared. More details at Exception Handling.
Go reports errors by returning an error object, all the information is available in such object and no other action is needed to clear the error condition. More details at Error handling and Go.
As long as the Python errors flow from Python to Go, it's straightforward to catch and translate them to Error objects; this is the exact duty of Go_CatchError function. It's less trivial what to do with errors in the context of a Python extension, where they are possibly reported to the Python interpreter.
These are the possible scenarios:
- the error is generated and handled in the Go context: nothing special here, the Python interpreter will never see this error and can be managed in a regular Go fashion
- the error is generated in the Python context and handled in the Go context: the error is handled as in the embedded interpreter situation via
Go_CatchError
, the Python interpreter generates the error but does not see it popping back from the Go context - the error is generated in the Go context and is reported to the Python interpreter: the Go error is translated to a Python exception according to the Python protocol
- the error is generated in the Python context, transits through the Go error paths and is eventually given back to the interpreter: all the information of the original Python exception has to be preserved so that the Go extension behaves transparently to the interpreter
- variation of case 4, while Go is handling an error coming in from Python a new Go error is triggered: the new error is passed back to the interpreter with
__cause__
and__context__
set accordingly (see Exception context)