1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo) 2 3 #include "Exceptions.h" 4 5 #include "JSIInteropModuleRegistry.h" 6 #include "JSReferencesCache.h" 7 8 namespace jni = facebook::jni; 9 10 namespace expo { 11 12 jni::local_ref<CodedException> CodedException::create(const std::string &message) { 13 return CodedException::newInstance(jni::make_jstring(message)); 14 } 15 16 std::string CodedException::getCode() { 17 const auto getCode = this->getClass()->getMethod<jni::JString()>("getCode"); 18 const auto code = getCode(this->self()); 19 return code->toStdString(); 20 } 21 22 std::optional<std::string> CodedException::getLocalizedMessage() { 23 const auto getLocalizedMessage = this->getClass() 24 ->getMethod<jni::JString()>("getLocalizedMessage"); 25 const auto message = getLocalizedMessage(this->self()); 26 if (message != nullptr) { 27 return message->toStdString(); 28 } 29 30 return std::nullopt; 31 } 32 33 jni::local_ref<JavaScriptEvaluateException> JavaScriptEvaluateException::create( 34 const std::string &message, 35 const std::string &jsStack 36 ) { 37 return JavaScriptEvaluateException::newInstance( 38 jni::make_jstring(message), 39 jni::make_jstring(jsStack) 40 ); 41 } 42 43 jni::local_ref<UnexpectedException> UnexpectedException::create(const std::string &message) { 44 return UnexpectedException::newInstance( 45 jni::make_jstring(message) 46 ); 47 } 48 49 void rethrowAsCodedError( 50 jsi::Runtime &rt, 51 JSIInteropModuleRegistry *registry, 52 jni::JniException &jniException 53 ) { 54 jni::local_ref<jni::JThrowable> unboxedThrowable = jniException.getThrowable(); 55 if (unboxedThrowable->isInstanceOf(CodedException::javaClassLocal())) { 56 auto codedException = jni::static_ref_cast<CodedException>(unboxedThrowable); 57 auto code = codedException->getCode(); 58 auto message = codedException->getLocalizedMessage(); 59 60 auto *codedErrorPointer = registry->jsRegistry->getOptionalObject<jsi::Function>( 61 JSReferencesCache::JSKeys::CODED_ERROR 62 ); 63 if (codedErrorPointer != nullptr) { 64 auto &jsCodedError = *codedErrorPointer; 65 66 throw jsi::JSError( 67 message.value_or(""), 68 rt, 69 jsCodedError.callAsConstructor( 70 rt, 71 jsi::String::createFromUtf8(rt, code), 72 jsi::String::createFromUtf8(rt, message.value_or("")) 73 ) 74 ); 75 } 76 } 77 78 // Rethrow error if we can't wrap it. 79 throw; 80 } 81 } // namespace expo 82