mirror of
https://github.com/mollyim/monero-wallet-sdk.git
synced 2025-02-05 01:15:37 -05:00
lib: throw C++ exceptions on exceptions from Java calls
This commit is contained in:
parent
56ecb91657
commit
a34ace5fc8
@ -29,7 +29,6 @@ class ScopedFd {
|
|||||||
if (!parcel_file_descriptor.is_null()) {
|
if (!parcel_file_descriptor.is_null()) {
|
||||||
m_fd = parcel_file_descriptor.callIntMethod(env,
|
m_fd = parcel_file_descriptor.callIntMethod(env,
|
||||||
ParcelFileDescriptor_detachFd);
|
ParcelFileDescriptor_detachFd);
|
||||||
LOG_FATAL_IF(checkException(env));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,11 +35,8 @@ bool RemoteNodeClient::is_connected(bool* ssl) {
|
|||||||
|
|
||||||
RemoteNodeClient::HttpResponse jvmToHttpResponse(JNIEnv* env, JvmRef<jobject>& j_http_response) {
|
RemoteNodeClient::HttpResponse jvmToHttpResponse(JNIEnv* env, JvmRef<jobject>& j_http_response) {
|
||||||
jint code = j_http_response.callIntMethod(env, HttpResponse_getCode);
|
jint code = j_http_response.callIntMethod(env, HttpResponse_getCode);
|
||||||
LOG_FATAL_IF(checkException(env));
|
|
||||||
jstring mime_type = j_http_response.callStringMethod(env, HttpResponse_getContentType);
|
jstring mime_type = j_http_response.callStringMethod(env, HttpResponse_getContentType);
|
||||||
LOG_FATAL_IF(checkException(env));
|
|
||||||
jobject body = j_http_response.callObjectMethod(env, HttpResponse_getBody);
|
jobject body = j_http_response.callObjectMethod(env, HttpResponse_getBody);
|
||||||
LOG_FATAL_IF(checkException(env));
|
|
||||||
return {
|
return {
|
||||||
code,
|
code,
|
||||||
(mime_type != nullptr) ? jvmToStdString(env, mime_type) : "",
|
(mime_type != nullptr) ? jvmToStdString(env, mime_type) : "",
|
||||||
@ -58,33 +55,34 @@ bool RemoteNodeClient::invoke(const boost::string_ref uri,
|
|||||||
for (const auto& p: additional_params) {
|
for (const auto& p: additional_params) {
|
||||||
header << p.first << ": " << p.second << "\r\n";
|
header << p.first << ": " << p.second << "\r\n";
|
||||||
}
|
}
|
||||||
ScopedJvmLocalRef<jobject> j_response = {
|
try {
|
||||||
env, m_remote_node_client.callObjectMethod(
|
ScopedJvmLocalRef<jobject> j_response = {
|
||||||
env, IRemoteNodeClient_makeRequest,
|
env, m_remote_node_client.callObjectMethod(
|
||||||
nativeToJvmString(env, method.data()).obj(),
|
env, IRemoteNodeClient_makeRequest,
|
||||||
nativeToJvmString(env, uri.data()).obj(),
|
nativeToJvmString(env, method.data()).obj(),
|
||||||
nativeToJvmString(env, header.str()).obj(),
|
nativeToJvmString(env, uri.data()).obj(),
|
||||||
nativeToJvmByteArray(env, body.data(), body.length()).obj()
|
nativeToJvmString(env, header.str()).obj(),
|
||||||
)
|
nativeToJvmByteArray(env, body.data(), body.length()).obj()
|
||||||
};
|
)
|
||||||
if (checkException(env)) {
|
};
|
||||||
|
m_response_info.clear();
|
||||||
|
if (j_response.is_null()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
HttpResponse http_response = jvmToHttpResponse(env, j_response);
|
||||||
|
if (http_response.code == 401) {
|
||||||
|
// Handle HTTP unauthorized in the same way as http_simple_client_template.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_response_info.m_response_code = http_response.code;
|
||||||
|
m_response_info.m_mime_tipe = http_response.content_type;
|
||||||
|
if (http_response.body.is_valid()) {
|
||||||
|
http_response.body.read(&m_response_info.m_body);
|
||||||
|
}
|
||||||
|
} catch (std::runtime_error& e) {
|
||||||
LOGE("Unhandled exception in RemoteNodeClient");
|
LOGE("Unhandled exception in RemoteNodeClient");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_response_info.clear();
|
|
||||||
if (j_response.is_null()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
HttpResponse http_response = jvmToHttpResponse(env, j_response);
|
|
||||||
if (http_response.code == 401) {
|
|
||||||
// Handle unauthorized in the same way as http_simple_client_template.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_response_info.m_response_code = http_response.code;
|
|
||||||
m_response_info.m_mime_tipe = http_response.content_type;
|
|
||||||
if (http_response.body.is_valid()) {
|
|
||||||
http_response.body.read(&m_response_info.m_body);
|
|
||||||
}
|
|
||||||
if (ppresponse_info) {
|
if (ppresponse_info) {
|
||||||
*ppresponse_info = std::addressof(m_response_info);
|
*ppresponse_info = std::addressof(m_response_info);
|
||||||
}
|
}
|
||||||
|
@ -104,34 +104,43 @@ void JvmRef<jobject>::callVoidMethod(JNIEnv* env,
|
|||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, method_id);
|
va_start(args, method_id);
|
||||||
env->CallVoidMethodV(obj(), method_id, args);
|
env->CallVoidMethodV(obj(), method_id, args);
|
||||||
|
throwRuntimeErrorOnException(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
jint JvmRef<jobject>::callIntMethod(JNIEnv* env,
|
jint JvmRef<jobject>::callIntMethod(JNIEnv* env,
|
||||||
jmethodID method_id, ...) const {
|
jmethodID method_id, ...) const {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, method_id);
|
va_start(args, method_id);
|
||||||
return env->CallIntMethodV(obj(), method_id, args);
|
jint ret = env->CallIntMethodV(obj(), method_id, args);
|
||||||
|
throwRuntimeErrorOnException(env);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
jboolean JvmRef<jobject>::callBooleanMethod(JNIEnv* env,
|
jboolean JvmRef<jobject>::callBooleanMethod(JNIEnv* env,
|
||||||
jmethodID method_id, ...) const {
|
jmethodID method_id, ...) const {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, method_id);
|
va_start(args, method_id);
|
||||||
return env->CallBooleanMethodV(obj(), method_id, args);
|
jboolean ret = env->CallBooleanMethodV(obj(), method_id, args);
|
||||||
|
throwRuntimeErrorOnException(env);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
jobject JvmRef<jobject>::callObjectMethod(JNIEnv* env,
|
jobject JvmRef<jobject>::callObjectMethod(JNIEnv* env,
|
||||||
jmethodID method_id, ...) const {
|
jmethodID method_id, ...) const {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, method_id);
|
va_start(args, method_id);
|
||||||
return env->CallObjectMethodV(obj(), method_id, args);
|
jobject ret = env->CallObjectMethodV(obj(), method_id, args);
|
||||||
|
throwRuntimeErrorOnException(env);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring JvmRef<jobject>::callStringMethod(JNIEnv* env,
|
jstring JvmRef<jobject>::callStringMethod(JNIEnv* env,
|
||||||
jmethodID method_id, ...) const {
|
jmethodID method_id, ...) const {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, method_id);
|
va_start(args, method_id);
|
||||||
return (jstring) env->CallObjectMethodV(obj(), method_id, args);
|
auto ret = (jstring) env->CallObjectMethodV(obj(), method_id, args);
|
||||||
|
throwRuntimeErrorOnException(env);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
jmethodID JvmRef<jobject>::getMethodId(JNIEnv* env,
|
jmethodID JvmRef<jobject>::getMethodId(JNIEnv* env,
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -18,14 +19,21 @@ JNIEnv* getJniEnv();
|
|||||||
JNIEnv* initializeJvm(JavaVM* jvm, int version);
|
JNIEnv* initializeJvm(JavaVM* jvm, int version);
|
||||||
|
|
||||||
// Checks for any Java exception and clears currently thrown exception.
|
// Checks for any Java exception and clears currently thrown exception.
|
||||||
static bool inline checkException(JNIEnv* env) {
|
static bool inline checkException(JNIEnv* env, bool log_exception = true) {
|
||||||
if (env->ExceptionCheck()) {
|
if (env->ExceptionCheck()) {
|
||||||
|
if (log_exception) env->ExceptionDescribe();
|
||||||
env->ExceptionClear();
|
env->ExceptionClear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void inline throwRuntimeErrorOnException(JNIEnv* env) {
|
||||||
|
if (checkException(env, false)) {
|
||||||
|
throw std::runtime_error("Uncaught exception returned from Java call");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// Originally these classes are from WebRTC and Chromium.
|
// Originally these classes are from WebRTC and Chromium.
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
@ -74,7 +74,6 @@ void JvmLogSink::write(const std::string& tag,
|
|||||||
ScopedJvmLocalRef<jstring> j_msg = nativeToJvmString(env, msg);
|
ScopedJvmLocalRef<jstring> j_msg = nativeToJvmString(env, msg);
|
||||||
m_logger.callVoidMethod(env, Logger_logFromNative,
|
m_logger.callVoidMethod(env, Logger_logFromNative,
|
||||||
pri_idx, j_tag.obj(), j_msg.obj());
|
pri_idx, j_tag.obj(), j_msg.obj());
|
||||||
LOG_FATAL_IF(checkException(env));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JvmLogSink::set_logger(JNIEnv* env, const JvmRef<jobject>& logger) {
|
void JvmLogSink::set_logger(JNIEnv* env, const JvmRef<jobject>& logger) {
|
||||||
|
@ -132,7 +132,6 @@ void Wallet::handleBalanceChanged(uint64_t at_block_height) {
|
|||||||
m_blockchain_height = at_block_height;
|
m_blockchain_height = at_block_height;
|
||||||
JNIEnv* env = getJniEnv();
|
JNIEnv* env = getJniEnv();
|
||||||
m_callback.callVoidMethod(env, Wallet_onRefresh, at_block_height, true);
|
m_callback.callVoidMethod(env, Wallet_onRefresh, at_block_height, true);
|
||||||
LOG_FATAL_IF(checkException(env));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wallet::handleNewBlock(uint64_t height) {
|
void Wallet::handleNewBlock(uint64_t height) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user