This was my first commit with changes in so many files, I hope my commit message follows the octave convention.
I was just going through the issues and this one seemed interesting (sorry for not posting anything on the issue page), so I did a little digging.
The actual problem was that boost wasn't able to extract the string from the exception. The execution went into the nested catch block. There PyErr_Print() printed the traceback but no error was raised for octave to notice.
So, I added the error ("pyexec: Exception caught"); line in each of the 3 pyeval, pycall & pyexec files. We should probably change the error message. But, we definitely need an error statement there to tell octave that error occured.
Pls review @Colin Macdonald@Mike Miller
I just update the commit message a bit.
Also, I forgot to mention that I tried to extract the string in many other ways like using char* or other data types with extract or using Py* python functions to extract the string. But they didn't work too.
With these changes, the execution does NOT go into the nested catch block for all the examples mention in #24 and the string is extracted properly for all exceptions.
I couldn't find a case in which the execution would go into the nested catch block, but still, I think we should have an error message in that too, just to be safe.
the error message should be something like "pyexec: Exception encountered while trying to throw exception".
Sorry I didn't explain clearly. After this PR is merged, pyexec ("raise NameError('oops')") will be caught as exception and the error text will be displayed as "pyexec: NameError: 'oops'"
The code will NOT reach that last catch in such cases now. Previously there was exception while extracting the text from exception message so the execution went into that last catch.
I couldn't find a case currently when execution will go into that last catch but I left it for completeness.
The error text in that case could be something to say that some exception was caught but the message could not be extracted!?
But why (error_already_set const &)? If this is some emergency catch-all, why isn't it just catch?
Well, As far as I remember, all the python exceptions are raised in C++ (by the python api) as error_already_set. Also, the boost functions that we are using here do the same. So, the code in the try block can only raise this exception. So, basically it is same as doing catch(...) for catching every exception.
You've got pyexec in the error text for all them
Oops. Sorry, I blindly pasted that line in all the files. I'll edit the text and update this commit.
The extracting of the error message seems complicated: but sounds like it was non-trivial so maybe it has to be that way. I'll let Mike comment on that.
What happens to the stack trace? I looks like it is not shown (?). Should we do PyErr_Print (); before calling fetch_exception_message? Or, if the stack trace wasn't shown before, then let's file a new bug for that...