Java director exception handling improvements

When a director method throws an exception and it is caught by DirectorException
and passed back to Java using DirectorException::raiseJavaException, the Java
stack trace now contains the original source line that threw the exception.

Director exception handling code improved slightly to add some missing
ExceptionClear calls before calling JNI code.
This commit is contained in:
William S Fulton 2017-11-10 19:50:22 +00:00
commit 7aa28e37ec
7 changed files with 74 additions and 44 deletions

View file

@ -3843,7 +3843,6 @@ handle the mapping of Java exceptions into C++ exceptions.
%feature("director:except") MyClass::method(int x) {
jthrowable $error = jenv->ExceptionOccurred();
if ($error) {
jenv->ExceptionClear();
if (Swig::ExceptionMatches(jenv, $error, "java/lang/IndexOutOfBoundsException"))
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, $error).message());
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/MyJavaException"))
@ -3921,7 +3920,6 @@ is used in the feature code. Consider the following, which also happens to be th
%feature("director:except") %{
jthrowable $error = jenv->ExceptionOccurred();
if ($error) {
jenv->ExceptionClear();
$directorthrowshandlers
Swig::DirectorException::raise(jenv, $error);
}
@ -3970,7 +3968,6 @@ the resulting code generated in the director method after calling up to Java wil
<pre>
jthrowable swigerror = jenv-&gt;ExceptionOccurred();
if (swigerror) {
jenv-&gt;ExceptionClear();
if (Swig::ExceptionMatches(jenv, swigerror, "java/lang/IndexOutOfBoundsException")) {
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, swigerror).message());
}
@ -3992,7 +3989,7 @@ this potential fate.
<p>Because the default code generation maps any unhandled Java exceptions to
<code>Swig::DirectorException</code>, any director methods that have exception
specifications may cause program termination. To simply ignore
unexpected exceptions, the default handling can be changed with:
unexpected exceptions, the default handling can be changed by adding:
</p>
<div class="code">
@ -4068,14 +4065,10 @@ DEFINE_EXCEPTION(ExceptionA)
DEFINE_EXCEPTION(ExceptionB)
DEFINE_EXCEPTION(Unexpected)
// Mark three methods to map director thrown exceptions.
%feature("director:except") MyClass::meth1(int);
%feature("director:except") MyClass::meth2;
%feature("director:except") meth3;
%typemap(directorthrows) MyNS::ExceptionA, MyNS::ExceptionB, MyNS::Unexpected %{
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/$javaclassname"))
if (Swig::ExceptionMatches(jenv, $error, "$packagepath/$javaclassname")) {
throw $1_type(Swig::JavaExceptionMessage(jenv, $error).message());
}
%}
DECLARE_EXCEPTION(ExceptionA)
@ -4084,6 +4077,8 @@ DECLARE_EXCEPTION(Unexpected)
%catches(MyNS::ExceptionA, MyNS::ExceptionB, MyNS::Unexpected) MyClass::meth2();
%feature("director") MyClass;
%inline {
class MyClass {
public:
@ -4100,13 +4095,13 @@ DECLARE_EXCEPTION(Unexpected)
In this case the three different "directorthrows" typemaps will be used
to generate the three different exception handlers for
<code>meth1</code>, <code>meth2</code> and <code>meth3</code>. The generated
handlers will have "if" blocks for each exception type specified, in
handlers will have "if" blocks for each exception type, where the exception types are listed in either
the exception specification or <code>%catches</code> feature.
</p>
<p>Note that the "directorthrows" typemaps are important
only if it is important for the exceptions passed through the C++
layer to be mapped to distinct C++ exceptions. If director methods
layer need to be mapped to distinct C++ exceptions. If director methods
are being called by C++ code that is itself wrapped in a
SWIG generated Java wrapper and access is always through this wrapper,
the default <code>Swig::DirectorException</code> class provides enough information