Loading...
Searching...
No Matches
errors.hpp
Go to the documentation of this file.
#pragma once
#include <jni/types.hpp>
#include <jni/traits.hpp>
#include <system_error>
#include <string>
namespace std
{
template <> struct is_error_code_enum<jni::error> : public true_type {};
}
namespace jni
{
inline const std::error_category& ErrorCategory()
{
class Impl : public std::error_category
{
public:
const char* name() const noexcept override
{
return "JNI";
}
std::string message(int ev) const override
{
switch (static_cast<error>(ev))
{
case jni_ok: return "OK";
case jni_err: return "Unspecified error";
case jni_edetached: return "Detached error";
case jni_eversion: return "Version error";
}
return "Unknown error";
}
};
static Impl impl;
return impl;
}
inline void CheckErrorCode(jint err)
{
if (err != JNI_OK) throw std::system_error(err, ErrorCategory());
}
// An exception class indicating the presence of a pending Java exception.
// Note that it does not extract the message or other information from the
// Java exception; it's not possible to do so without clearing the pending
// Java exception, and the calling code needs the option not to do that.
// In most cases, the desired behavior is that the thrown PendingJavaException
// is caught by an exception handler just before returning to JVM control, and
// discarded there. Upon returning to JVM control, Java exception handling
// will take over, processing the still-pending Java exception.
class PendingJavaException {};
template < class R >
R CheckJavaException(JNIEnv& env, R&& r)
{
if (env.ExceptionCheck()) throw PendingJavaException();
return std::move(r);
}
inline void CheckJavaException(JNIEnv& env)
{
if (env.ExceptionCheck()) throw PendingJavaException();
}
inline void CheckJavaExceptionThenErrorCode(JNIEnv& env, jint err)
{
CheckJavaException(env);
CheckErrorCode(err);
}
inline ::jclass JavaErrorClass(JNIEnv& env)
{
return env.FindClass("java/lang/Error");
}
// A function to be called from within a try / catch wrapper for a native method:
//
// void nativeMethod(JNIEnv* env, ...)
// {
// try
// {
// ...
// }
// catch (...)
// {
// jni::ThrowJavaError(*env, std::current_exception());
// }
// }
//
// `PendingJavaException` is caught and ignored, other exceptions are converted to
// a pending Java exception of class `java.lang.Error`.
inline void ThrowJavaError(JNIEnv& env, std::exception_ptr e)
{
try
{
std::rethrow_exception(e);
}
catch (const PendingJavaException&)
{
}
catch (const std::exception& e)
{
env.ThrowNew(JavaErrorClass(env), e.what());
}
catch (...)
{
env.ThrowNew(JavaErrorClass(env), "unknown native exception");
}
}
}
jni::PendingJavaException
Definition errors.hpp:58
jni
Definition advanced_ownership.hpp:6
jni::CheckErrorCode
void CheckErrorCode(jint err)
Definition errors.hpp:43
jni::ThrowJavaError
void ThrowJavaError(JNIEnv &env, std::exception_ptr e)
Definition errors.hpp:101
jni::CheckJavaException
R CheckJavaException(JNIEnv &env, R &&r)
Definition errors.hpp:61
jni::ErrorCategory
const std::error_category & ErrorCategory()
Definition errors.hpp:16
jni::error
error
Definition types.hpp:91
jni::jni_err
@ jni_err
Definition types.hpp:93
jni::jni_ok
@ jni_ok
Definition types.hpp:92
jni::jni_eversion
@ jni_eversion
Definition types.hpp:95
jni::jni_edetached
@ jni_edetached
Definition types.hpp:94
jni::CheckJavaExceptionThenErrorCode
void CheckJavaExceptionThenErrorCode(JNIEnv &env, jint err)
Definition errors.hpp:72
jni::JavaErrorClass
inline ::jclass JavaErrorClass(JNIEnv &env)
Definition errors.hpp:79
std
Definition errors.hpp:10
traits.hpp
types.hpp