diff --git a/doc/classes/JavaClassWrapper.xml b/doc/classes/JavaClassWrapper.xml index b43e149e9fef..e8c5712f1bf6 100644 --- a/doc/classes/JavaClassWrapper.xml +++ b/doc/classes/JavaClassWrapper.xml @@ -15,10 +15,18 @@ print(datetime.format(formatter)) [/codeblock] + [b]Warning:[/b] When calling Java methods, be sure to check [method JavaClassWrapper.get_exception] to check if the method threw an exception. + + + + Returns the Java exception from the last call into a Java class. If there was no exception, it will return [code]null[/code]. + [b]Note:[/b] This method only works on Android. On every other platform, this method will always return [code]null[/code]. + + diff --git a/platform/android/api/api.cpp b/platform/android/api/api.cpp index 3e71a66b4cc0..86051a87f3b4 100644 --- a/platform/android/api/api.cpp +++ b/platform/android/api/api.cpp @@ -70,6 +70,7 @@ void JavaObject::_bind_methods() { void JavaClassWrapper::_bind_methods() { ClassDB::bind_method(D_METHOD("wrap", "name"), &JavaClassWrapper::wrap); + ClassDB::bind_method(D_METHOD("get_exception"), &JavaClassWrapper::get_exception); } #if !defined(ANDROID_ENABLED) diff --git a/platform/android/api/java_class_wrapper.h b/platform/android/api/java_class_wrapper.h index 21482a45c2c1..ae09a9d596aa 100644 --- a/platform/android/api/java_class_wrapper.h +++ b/platform/android/api/java_class_wrapper.h @@ -271,6 +271,8 @@ class JavaClassWrapper : public Object { bool _get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, String &strsig); #endif + Ref exception; + Ref _wrap(const String &p_class, bool p_allow_private_methods_access); static JavaClassWrapper *singleton; @@ -285,6 +287,10 @@ class JavaClassWrapper : public Object { return _wrap(p_class, false); } + Ref get_exception() { + return exception; + } + #ifdef ANDROID_ENABLED Ref wrap_jclass(jclass p_class, bool p_allow_private_methods_access = false); #endif diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp index a690a4f691e9..c19196ae8713 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -517,6 +517,20 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, env->DeleteLocalRef(E); } + jobject exception = env->ExceptionOccurred(); + if (exception) { + env->ExceptionClear(); + + jclass java_class = env->GetObjectClass(exception); + Ref java_class_wrapped = JavaClassWrapper::singleton->wrap_jclass(java_class); + env->DeleteLocalRef(java_class); + + JavaClassWrapper::singleton->exception.instantiate(java_class_wrapped, exception); + env->DeleteLocalRef(exception); + } else { + JavaClassWrapper::singleton->exception.unref(); + } + return success; }