lime
Lime is a C++ library implementing Open Whisper System Signal protocol
errors.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <jni/types.hpp>
4 #include <jni/traits.hpp>
5 
6 #include <system_error>
7 #include <string>
8 
9 namespace std
10  {
11  template <> struct is_error_code_enum<jni::error> : public true_type {};
12  }
13 
14 namespace jni
15  {
16  inline const std::error_category& ErrorCategory()
17  {
18  class Impl : public std::error_category
19  {
20  public:
21  const char* name() const noexcept override
22  {
23  return "JNI";
24  }
25 
26  std::string message(int ev) const override
27  {
28  switch (static_cast<error>(ev))
29  {
30  case jni_ok: return "OK";
31  case jni_err: return "Unspecified error";
32  case jni_edetached: return "Detached error";
33  case jni_eversion: return "Version error";
34  }
35  return "Unknown error";
36  }
37  };
38 
39  static Impl impl;
40  return impl;
41  }
42 
43  inline void CheckErrorCode(jint err)
44  {
45  if (err != JNI_OK) throw std::system_error(err, ErrorCategory());
46  }
47 
48 
49  // An exception class indicating the presence of a pending Java exception.
50  // Note that it does not extract the message or other information from the
51  // Java exception; it's not possible to do so without clearing the pending
52  // Java exception, and the calling code needs the option not to do that.
53  // In most cases, the desired behavior is that the thrown PendingJavaException
54  // is caught by an exception handler just before returning to JVM control, and
55  // discarded there. Upon returning to JVM control, Java exception handling
56  // will take over, processing the still-pending Java exception.
57 
59 
60  template < class R >
61  R CheckJavaException(JNIEnv& env, R&& r)
62  {
63  if (env.ExceptionCheck()) throw PendingJavaException();
64  return std::move(r);
65  }
66 
67  inline void CheckJavaException(JNIEnv& env)
68  {
69  if (env.ExceptionCheck()) throw PendingJavaException();
70  }
71 
72  inline void CheckJavaExceptionThenErrorCode(JNIEnv& env, jint err)
73  {
74  CheckJavaException(env);
75  CheckErrorCode(err);
76  }
77 
78 
79  inline ::jclass JavaErrorClass(JNIEnv& env)
80  {
81  return env.FindClass("java/lang/Error");
82  }
83 
84  // A function to be called from within a try / catch wrapper for a native method:
85  //
86  // void nativeMethod(JNIEnv* env, ...)
87  // {
88  // try
89  // {
90  // ...
91  // }
92  // catch (...)
93  // {
94  // jni::ThrowJavaError(*env, std::current_exception());
95  // }
96  // }
97  //
98  // `PendingJavaException` is caught and ignored, other exceptions are converted to
99  // a pending Java exception of class `java.lang.Error`.
100 
101  inline void ThrowJavaError(JNIEnv& env, std::exception_ptr e)
102  {
103  try
104  {
105  std::rethrow_exception(e);
106  }
107  catch (const PendingJavaException&)
108  {
109  }
110  catch (const std::exception& e)
111  {
112  env.ThrowNew(JavaErrorClass(env), e.what());
113  }
114  catch (...)
115  {
116  env.ThrowNew(JavaErrorClass(env), "unknown native exception");
117  }
118  }
119  }
Definition: errors.hpp:58
void CheckJavaExceptionThenErrorCode(JNIEnv &env, jint err)
Definition: errors.hpp:72
inline ::jclass JavaErrorClass(JNIEnv &env)
Definition: errors.hpp:79
Definition: errors.hpp:9
void CheckErrorCode(jint err)
Definition: errors.hpp:43
void ThrowJavaError(JNIEnv &env, std::exception_ptr e)
Definition: errors.hpp:101
error
Definition: types.hpp:90
Definition: advanced_ownership.hpp:5
Definition: types.hpp:94
Definition: types.hpp:93
Definition: types.hpp:95
const std::error_category & ErrorCategory()
Definition: errors.hpp:16
void CheckJavaException(JNIEnv &env)
Definition: errors.hpp:67
Definition: types.hpp:92