Skip to content

Commit 11d8e2e

Browse files
committed
Merge pull request godotengine#102862 from dsnopek/java-class-wrapper-get-exception
JavaClassWrapper: Allow handling exceptions (rather than just crashing)
2 parents 5da66eb + 5d69d20 commit 11d8e2e

File tree

4 files changed

+29
-0
lines changed

4 files changed

+29
-0
lines changed

doc/classes/JavaClassWrapper.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,18 @@
1515

1616
print(datetime.format(formatter))
1717
[/codeblock]
18+
[b]Warning:[/b] When calling Java methods, be sure to check [method JavaClassWrapper.get_exception] to check if the method threw an exception.
1819
</description>
1920
<tutorials>
2021
</tutorials>
2122
<methods>
23+
<method name="get_exception">
24+
<return type="JavaObject" />
25+
<description>
26+
Returns the Java exception from the last call into a Java class. If there was no exception, it will return [code]null[/code].
27+
[b]Note:[/b] This method only works on Android. On every other platform, this method will always return [code]null[/code].
28+
</description>
29+
</method>
2230
<method name="wrap">
2331
<return type="JavaClass" />
2432
<param index="0" name="name" type="String" />

platform/android/api/api.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ void JavaObject::_bind_methods() {
7070

7171
void JavaClassWrapper::_bind_methods() {
7272
ClassDB::bind_method(D_METHOD("wrap", "name"), &JavaClassWrapper::wrap);
73+
ClassDB::bind_method(D_METHOD("get_exception"), &JavaClassWrapper::get_exception);
7374
}
7475

7576
#if !defined(ANDROID_ENABLED)

platform/android/api/java_class_wrapper.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ class JavaClassWrapper : public Object {
271271
bool _get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, String &strsig);
272272
#endif
273273

274+
Ref<JavaObject> exception;
275+
274276
Ref<JavaClass> _wrap(const String &p_class, bool p_allow_private_methods_access);
275277

276278
static JavaClassWrapper *singleton;
@@ -285,6 +287,10 @@ class JavaClassWrapper : public Object {
285287
return _wrap(p_class, false);
286288
}
287289

290+
Ref<JavaObject> get_exception() {
291+
return exception;
292+
}
293+
288294
#ifdef ANDROID_ENABLED
289295
Ref<JavaClass> wrap_jclass(jclass p_class, bool p_allow_private_methods_access = false);
290296
#endif

platform/android/java_class_wrapper.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,20 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
517517
env->DeleteLocalRef(E);
518518
}
519519

520+
jobject exception = env->ExceptionOccurred();
521+
if (exception) {
522+
env->ExceptionClear();
523+
524+
jclass java_class = env->GetObjectClass(exception);
525+
Ref<JavaClass> java_class_wrapped = JavaClassWrapper::singleton->wrap_jclass(java_class);
526+
env->DeleteLocalRef(java_class);
527+
528+
JavaClassWrapper::singleton->exception.instantiate(java_class_wrapped, exception);
529+
env->DeleteLocalRef(exception);
530+
} else {
531+
JavaClassWrapper::singleton->exception.unref();
532+
}
533+
520534
return success;
521535
}
522536

0 commit comments

Comments
 (0)