1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2 
3 #pragma once
4 
5 #include <fbjni/fbjni.h>
6 #include <jsi/jsi.h>
7 
8 #include <optional>
9 
10 namespace jni = facebook::jni;
11 namespace jsi = facebook::jsi;
12 
13 namespace expo {
14 
15 class JSIInteropModuleRegistry;
16 
17 /**
18  * A convenient wrapper for the Kotlin CodedException.
19  * It can be used with the `jni::throwNewJavaException` function to throw a cpp exception that
20  * will be automatically changed to the corresponding Java/Kotlin exception.
21  * `jni::throwNewJavaException` creates and throws a C++ exception which wraps a Java exception,
22  * so the C++ flow is interrupted. Then, when translatePendingCppExceptionToJavaException
23  * is called at the topmost level of the native stack, the wrapped Java exception is thrown to the java caller.
24  */
25 class CodedException : public jni::JavaClass<CodedException, jni::JThrowable> {
26 public:
27   static auto constexpr kJavaDescriptor = "Lexpo/modules/kotlin/exception/CodedException;";
28 
29   static jni::local_ref<CodedException> create(const std::string &message);
30 
31   std::string getCode();
32 
33   std::optional<std::string> getLocalizedMessage();
34 };
35 
36 /**
37  * A convenient wrapper for the Kotlin JavaScriptEvaluateException.
38  */
39 class JavaScriptEvaluateException
40   : public jni::JavaClass<JavaScriptEvaluateException, CodedException> {
41 public:
42   static auto constexpr kJavaDescriptor = "Lexpo/modules/kotlin/exception/JavaScriptEvaluateException;";
43 
44   static jni::local_ref<JavaScriptEvaluateException> create(
45     const std::string &message,
46     const std::string &jsStack
47   );
48 };
49 
50 /**
51  * A convenient wrapper for the Kotlin UnexpectedException.
52  */
53 class UnexpectedException
54   : public jni::JavaClass<UnexpectedException, CodedException> {
55 public:
56   static auto constexpr kJavaDescriptor = "Lexpo/modules/kotlin/exception/UnexpectedException;";
57 
58   static jni::local_ref<UnexpectedException> create(
59     const std::string &message
60   );
61 };
62 
63 /**
64  * Tries to rethrow an jni::JniException as a js version of the CodedException
65  */
66 [[noreturn]] void rethrowAsCodedError(
67   jsi::Runtime &rt,
68   JSIInteropModuleRegistry *registry,
69   jni::JniException &jniException
70 );
71 } // namespace expo
72