pyjnius icon indicating copy to clipboard operation
pyjnius copied to clipboard

Return the actual Java Exception object on Exception?

Open jk1ng opened this issue 8 years ago • 9 comments

Hi!

Just wondering, I couldn't seem to be able to get the actual Java Exception object returned as an Exception? Is this by design, or is this something that could be part of future features?

For example, it would be nice to be able to do:

MyException = jnius.autoclass("myjavaprogram.exceptions.MyException")
MyClass = jnius.autoclass("myjavaprogram.MyClass")
try:
  MyClass.doSomethingThatThrowsAnException()
except MyException:
  # Do something
  pass
except JavaException:
  # Do something else
  pass

As an addendum, MyException would also have to inherit from jnius.JavaException

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/30741053-return-the-actual-java-exception-object-on-exception?utm_campaign=plugin&utm_content=tracker%2F77133&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F77133&utm_medium=issues&utm_source=github).

jk1ng avatar Feb 10 '16 23:02 jk1ng

FYI - That could be difficult to do. Might be possible, but no guarantees.

However, JavaException does have a classname attribute:

MyClass = jnius.autoclass('myjavaprogram.MyClass')
try:
    MyClass.doSomethingThatThrowsAnException()
except JavaException as e:
    if e.classname == 'myjavaprogram.exceptions.MyException':
        # Do something
        pass
    else:
        # Do something else
        pass

kived avatar Feb 10 '16 23:02 kived

Yeah, I saw that, but I was hoping that we might be able to do better. I'm concerned that certain methods or data might be lost with just that approach.

I might try to take a stab at some part of it, but my schedule is really packed for the next few weeks.

jk1ng avatar Feb 11 '16 20:02 jk1ng

Ah, I see what you're saying. You want access to the actual Java exception object, and we don't provide that. I'm sure that could be changed, I'm just not sure if we'll ever have native Python wrappers to allow catching specific Java exceptions. But we could probably have something like e.java_exception as a reference to the proxied Java exception object.

kived avatar Feb 11 '16 20:02 kived

@kived Any further thoughts on this? I'd really like to be able to get a Java stacktrace.

jcrotinger avatar May 06 '20 17:05 jcrotinger

i didn't try it, but JavaException has a stacktrace attribute, that seems to be populated with a conversion of the java stacktrace, in check_exception() ? https://github.com/kivy/pyjnius/blob/master/jnius/jnius_utils.pxi#L91

that was already the case in 2016 when this bug was opened though, so there must be something i'm missing.

tshirtman avatar May 06 '20 22:05 tshirtman

Doesn't seem to be there:

print(f"exception             : {exception}")
print(f"type                  : {type(exception)}")
print(f"type(e.stacktrace)    : {type(exception.stacktrace)}")
print(f"type(e.innermessage)  : {type(exception.innermessage)}")
print(f"type(e.classname)     : {type(exception.classname)}")

prints:

exception             : Invalid call, number of argument mismatch, got 0 need 1
type                  : <class 'jnius.JavaException'>
type(e.stacktrace)    : <class 'NoneType'>
type(e.innermessage)  : <class 'NoneType'>
type(e.classname)     : <class 'NoneType'>

Looking at jnius_utils.pxi, it isn't clear where this is thrown from.

jcrotinger avatar May 07 '20 23:05 jcrotinger

i would assume there https://github.com/kivy/pyjnius/blob/master/jnius/jnius_export_class.pxi#L831-L836

which would mean the error didn't happen in java, it happened in python before the call to the java function, so there is no java stacktrace to report.

edit: the latter part of the message (after "got {one}") was added in the latest version of pyjnius, released last weekend, which also solved some bugs in the lookup of methods, you might want to upgrade and try with that version.

tshirtman avatar May 07 '20 23:05 tshirtman

Got it - thanks! It would be nice if the message included the method name, since it must be known.

I was able to print the stack trace with

      print("".join(traceback.TracebackException.from_exception(e).format()))

and sorted it out.

(The confusion was that the code had something like foo.bar(a.getX(), a.getY(), ...) where foo and a are Java objects. I assumed the problem was somewhere down in foo.bar and only later realized that it wasn't getting that far. Debugging this interlanguage stuff can be a headache so more info in exceptions helps!)

jcrotinger avatar May 08 '20 00:05 jcrotinger

See also the discussion in #623 about how to better display the stack-trace.

Julian-O avatar Oct 28 '23 01:10 Julian-O