pyjnius
pyjnius copied to clipboard
Return the actual Java Exception object on Exception?
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
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
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.
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 Any further thoughts on this? I'd really like to be able to get a Java stacktrace.
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.
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.
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.
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!)
See also the discussion in #623 about how to better display the stack-trace.