Skip to content

Commit 2ed1eaf

Browse files
committed
Merge pull request #277 from NativeScript/plamen5kov/error_handling_refactor
error handling introducing c++ exceptions
2 parents 1e7fad7 + ea8956c commit 2ed1eaf

37 files changed

+2523
-1033
lines changed

src/jni/Android.mk

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,19 @@ include $(PREBUILT_STATIC_LIBRARY)
6262
include $(CLEAR_VARS)
6363
LOCAL_CPPFLAGS += -std=c++11
6464
LOCAL_MODULE := NativeScript
65-
LOCAL_SRC_FILES := com_tns_AssetExtractor.cpp com_tns_Platform.cpp com_tns_JsDebugger.cpp com_tns_NativeScriptActity.cpp \
66-
JEnv.cpp DirectBuffer.cpp \
65+
LOCAL_SRC_FILES := com_tns_AssetExtractor.cpp AssetExtractor.cpp\
66+
com_tns_Platform.cpp NativePlatform.cpp \
67+
com_tns_JsDebugger.cpp com_tns_NativeScriptActity.cpp \
68+
JEnv.cpp DirectBuffer.cpp NativeScriptException.cpp \
6769
JsDebugger.cpp SimpleAllocator.cpp \
6870
NativeScriptRuntime.cpp MetadataNode.cpp MetadataTreeNode.cpp MetadataReader.cpp \
6971
MethodCache.cpp JavaObjectArrayCache.cpp \
7072
JniLocalRef.cpp JniSignatureParser.cpp \
7173
ArgConverter.cpp JsArgToArrayConverter.cpp JsArgConverter.cpp V8GlobalHelpers.cpp V8StringConstants.cpp \
7274
FieldAccessor.cpp ArrayElementAccessor.cpp \
73-
ExceptionUtil.cpp Util.cpp Logger.cpp Profiler.cpp \
75+
Util.cpp Logger.cpp Profiler.cpp \
7476
ObjectManager.cpp NumericCasts.cpp WeakRef.cpp \
75-
MetadataMethodInfo.cpp SimpleProfiler.cpp JType.cpp File.cpp Module.cpp Constants.cpp
77+
MetadataMethodInfo.cpp SimpleProfiler.cpp JType.cpp File.cpp Module.cpp Constants.cpp
7678

7779
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
7880
LOCAL_LDLIBS := -llog -landroid -lz

src/jni/Application.mk

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@ APP_OPTIM := debug
99

1010
#The new ndks require this or build fails
1111
APP_CFLAGS += -Wno-error=format-security
12-
APP_CFLAGS += -g
12+
APP_CFLAGS += -g
13+
14+
#Turn on C++ exceptions
15+
APP_CPPFLAGS += -fexceptions

src/jni/ArgConverter.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "V8GlobalHelpers.h"
66
#include "V8StringConstants.h"
77
#include "NativeScriptAssert.h"
8+
#include "NativeScriptException.h"
89
#include "JType.h"
910
#include <assert.h>
1011
#include <sstream>
@@ -32,23 +33,53 @@ void ArgConverter::Init(JavaVM *jvm)
3233

3334
void ArgConverter::NativeScriptLongValueOfFunctionCallback(const v8::FunctionCallbackInfo<Value>& args)
3435
{
36+
try {
3537
auto isolate = Isolate::GetCurrent();
3638
args.GetReturnValue().Set(Number::New(isolate, numeric_limits<double>::quiet_NaN()));
39+
} catch (NativeScriptException& e) {
40+
e.ReThrowToV8();
41+
}
42+
catch (exception e) {
43+
DEBUG_WRITE("Error: c++ exception: %s", e.what());
44+
}
45+
catch (...) {
46+
DEBUG_WRITE("Error: c++ exception!");
47+
}
3748
}
3849

3950
void ArgConverter::NativeScriptLongToStringFunctionCallback(const v8::FunctionCallbackInfo<Value>& args)
4051
{
52+
try {
4153
args.GetReturnValue().Set(args.This()->Get(V8StringConstants::GetValue()));
54+
} catch (NativeScriptException& e) {
55+
e.ReThrowToV8();
56+
}
57+
catch (exception e) {
58+
DEBUG_WRITE("Error: c++ exception: %s", e.what());
59+
}
60+
catch (...) {
61+
DEBUG_WRITE("Error: c++ exception!");
62+
}
4263
}
4364

4465
void ArgConverter::NativeScriptLongFunctionCallback(const v8::FunctionCallbackInfo<Value>& args)
4566
{
67+
try {
4668
auto isolate = Isolate::GetCurrent();
4769
args.This()->SetHiddenValue(V8StringConstants::GetJavaLong(), Boolean::New(isolate, true));
4870
args.This()->SetHiddenValue(V8StringConstants::GetMarkedAsLong(), args[0]);
4971
args.This()->Set(V8StringConstants::GetValue(), args[0]);
5072

5173
args.This()->SetPrototype(Local<NumberObject>::New(Isolate::GetCurrent(), *NAN_NUMBER_OBJECT));
74+
} catch (NativeScriptException& e) {
75+
e.ReThrowToV8();
76+
}
77+
catch (exception e) {
78+
DEBUG_WRITE("Error: c++ exception: %s", e.what());
79+
}
80+
catch (...) {
81+
DEBUG_WRITE("Error: c++ exception!");
82+
}
5283
}
5384

5485

src/jni/ArrayElementAccessor.cpp

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "Util.h"
66
#include "V8GlobalHelpers.h"
77
#include "NativeScriptAssert.h"
8+
#include "NativeScriptException.h"
89
#include "JType.h"
910
#include <assert.h>
1011

@@ -39,14 +40,14 @@ Local<Value> ArrayElementAccessor::GetArrayElement(const Local<Object>& array, u
3940
jbooleanArray boolArr = reinterpret_cast<jbooleanArray>(arr);
4041
jboolean boolArrValue;
4142
env.GetBooleanArrayRegion(boolArr, startIndex, length, &boolArrValue);
42-
value = CheckForArrayAccessException(env, elementSignature, &boolArrValue);
43+
value = ConvertToJsValue(env, elementSignature, &boolArrValue);
4344
}
4445
else if (elementSignature == "B")
4546
{
4647
jbyteArray byteArr = reinterpret_cast<jbyteArray>(arr);
4748
jbyte byteArrValue;
4849
env.GetByteArrayRegion(byteArr, startIndex, length, &byteArrValue);
49-
value = CheckForArrayAccessException(env, elementSignature, &byteArrValue);
50+
value = ConvertToJsValue(env, elementSignature, &byteArrValue);
5051
}
5152
else if (elementSignature == "C")
5253
{
@@ -55,48 +56,48 @@ Local<Value> ArrayElementAccessor::GetArrayElement(const Local<Object>& array, u
5556
env.GetCharArrayRegion(charArr, startIndex, length, &charArrValue);
5657
JniLocalRef s(env.NewString(&charArrValue, 1));
5758
const char* singleChar = env.GetStringUTFChars(s, &isCopy);
58-
value = CheckForArrayAccessException(env, elementSignature, singleChar);
59+
value = ConvertToJsValue(env, elementSignature, singleChar);
5960
env.ReleaseStringUTFChars(s, singleChar);
6061
}
6162
else if (elementSignature == "S")
6263
{
6364
jshortArray shortArr = reinterpret_cast<jshortArray>(arr);
6465
jshort shortArrValue;
6566
env.GetShortArrayRegion(shortArr, startIndex, length, &shortArrValue);
66-
value = CheckForArrayAccessException(env, elementSignature, &shortArrValue);
67+
value = ConvertToJsValue(env, elementSignature, &shortArrValue);
6768
}
6869
else if (elementSignature == "I")
6970
{
7071
jintArray intArr = reinterpret_cast<jintArray>(arr);
7172
jint intArrValue;
7273
env.GetIntArrayRegion(intArr, startIndex, length, &intArrValue);
73-
value = CheckForArrayAccessException(env, elementSignature, &intArrValue);
74+
value = ConvertToJsValue(env, elementSignature, &intArrValue);
7475
}
7576
else if (elementSignature == "J")
7677
{
7778
jlongArray longArr = reinterpret_cast<jlongArray>(arr);
7879
jlong longArrValue;
7980
env.GetLongArrayRegion(longArr, startIndex, length, &longArrValue);
80-
value = CheckForArrayAccessException(env, elementSignature, &longArrValue);
81+
value = ConvertToJsValue(env, elementSignature, &longArrValue);
8182
}
8283
else if (elementSignature == "F")
8384
{
8485
jfloatArray floatArr = reinterpret_cast<jfloatArray>(arr);
8586
jfloat floatArrValue;
8687
env.GetFloatArrayRegion(floatArr, startIndex, length, &floatArrValue);
87-
value = CheckForArrayAccessException(env, elementSignature, &floatArrValue);
88+
value = ConvertToJsValue(env, elementSignature, &floatArrValue);
8889
}
8990
else if (elementSignature == "D")
9091
{
9192
jdoubleArray doubleArr = reinterpret_cast<jdoubleArray>(arr);
9293
jdouble doubleArrValue;
9394
env.GetDoubleArrayRegion(doubleArr, startIndex, length, &doubleArrValue);
94-
value = CheckForArrayAccessException(env, elementSignature, &doubleArrValue);
95+
value = ConvertToJsValue(env, elementSignature, &doubleArrValue);
9596
}
9697
else
9798
{
9899
jobject result = env.GetObjectArrayElement(reinterpret_cast<jobjectArray>(arr), index);
99-
value = CheckForArrayAccessException(env, elementSignature, &result);
100+
value = ConvertToJsValue(env, elementSignature, &result);
100101
env.DeleteLocalRef(result);
101102
}
102103

@@ -116,19 +117,19 @@ void ArrayElementAccessor::SetArrayElement(const Local<Object>& array, uint32_t
116117
const string elementSignature = arraySignature.substr(1);
117118
jboolean isCopy = false;
118119

119-
if (elementSignature == "Z")
120+
if (elementSignature == "Z") //bool
120121
{
121122
jboolean boolElementValue = (jboolean) value->BooleanValue();
122123
jbooleanArray boolArr = reinterpret_cast<jbooleanArray>(arr);
123124
env.SetBooleanArrayRegion(boolArr, index, 1, &boolElementValue);
124125
}
125-
else if (elementSignature == "B")
126+
else if (elementSignature == "B") //byte
126127
{
127128
jbyte byteElementValue = (jbyte) value->Int32Value();
128129
jbyteArray byteArr = reinterpret_cast<jbyteArray>(arr);
129130
env.SetByteArrayRegion(byteArr, index, 1, &byteElementValue);
130131
}
131-
else if (elementSignature == "C")
132+
else if (elementSignature == "C") //char
132133
{
133134
String::Utf8Value utf8(value->ToString());
134135
JniLocalRef s(env.NewString((jchar*) *utf8, 1));
@@ -138,19 +139,19 @@ void ArrayElementAccessor::SetArrayElement(const Local<Object>& array, uint32_t
138139
jcharArray charArr = reinterpret_cast<jcharArray>(arr);
139140
env.SetCharArrayRegion(charArr, index, 1, &charElementValue);
140141
}
141-
else if (elementSignature == "S")
142+
else if (elementSignature == "S") //short
142143
{
143144
jshort shortElementValue = (jshort) value->Int32Value();
144145
jshortArray shortArr = reinterpret_cast<jshortArray>(arr);
145146
env.SetShortArrayRegion(shortArr, index, 1, &shortElementValue);
146147
}
147-
else if (elementSignature == "I")
148+
else if (elementSignature == "I") //int
148149
{
149150
jint intElementValue = value->Int32Value();
150151
jintArray intArr = reinterpret_cast<jintArray>(arr);
151152
env.SetIntArrayRegion(intArr, index, 1, &intElementValue);
152153
}
153-
else if (elementSignature == "J")
154+
else if (elementSignature == "J") //long
154155
{
155156
jlong longElementValue;
156157
if (value->IsObject())
@@ -164,19 +165,19 @@ void ArrayElementAccessor::SetArrayElement(const Local<Object>& array, uint32_t
164165
jlongArray longArr = reinterpret_cast<jlongArray>(arr);
165166
env.SetLongArrayRegion(longArr, index, 1, &longElementValue);
166167
}
167-
else if (elementSignature == "F")
168+
else if (elementSignature == "F") //float
168169
{
169170
jfloat floatElementValue = (jfloat) value->NumberValue();
170171
jfloatArray floatArr = reinterpret_cast<jfloatArray>(arr);
171172
env.SetFloatArrayRegion(floatArr, index, 1, &floatElementValue);
172173
}
173-
else if (elementSignature == "D")
174+
else if (elementSignature == "D") //double
174175
{
175176
jdouble doubleElementValue = (jdouble) value->NumberValue();
176177
jdoubleArray doubleArr = reinterpret_cast<jdoubleArray>(arr);
177178
env.SetDoubleArrayRegion(doubleArr, index, 1, &doubleElementValue);
178179
}
179-
else
180+
else //string or object
180181
{
181182
bool isReferenceType = value->IsObject() || value->IsString();
182183
if (isReferenceType)
@@ -193,35 +194,23 @@ void ArrayElementAccessor::SetArrayElement(const Local<Object>& array, uint32_t
193194
else
194195
{
195196
JsArgToArrayConverter::Error err = argConverter.GetError();
196-
ExceptionUtil::GetInstance()->ThrowExceptionToJs(err.msg);
197-
return;
197+
throw NativeScriptException(string(err.msg));
198198
}
199199
}
200200
else
201201
{
202-
ExceptionUtil::GetInstance()->ThrowExceptionToJs("Cannot assign primitive value to array of objects.");
203-
return;
202+
throw NativeScriptException(string("Cannot assign primitive value to array of objects."));
204203
}
205204
}
206205
}
207206

208-
Local<Value> ArrayElementAccessor::CheckForArrayAccessException(JEnv& env, const string& elementSignature, const void *value)
207+
Local<Value> ArrayElementAccessor::ConvertToJsValue(JEnv& env, const string& elementSignature, const void *value)
209208
{
210209
Local<Value> jsValue;
211210

212211
auto isolate = Isolate::GetCurrent();
213212

214-
JniLocalRef exc(env.ExceptionOccurred());
215-
if (nullptr != (jthrowable) exc)
216-
{
217-
DEBUG_WRITE("Error during getting array element");
218-
// env.ExceptionDescribe(); We will print this manually in the ExceptionUtil
219-
env.ExceptionClear();
220-
string errMsg;
221-
ExceptionUtil::GetInstance()->GetExceptionMessage(env, exc, errMsg);
222-
ExceptionUtil::GetInstance()->ThrowExceptionToJs(errMsg);
223-
}
224-
else if (elementSignature == "Z")
213+
if (elementSignature == "Z")
225214
{
226215
jsValue = Boolean::New(isolate, *(jboolean*) value);
227216
}

src/jni/ArrayElementAccessor.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "v8.h"
66
#include <string>
77
#include "ObjectManager.h"
8-
#include "ExceptionUtil.h"
98

109
namespace tns
1110
{
@@ -19,7 +18,7 @@ namespace tns
1918
void SetArrayElement(const v8::Local<v8::Object>& array, uint32_t index, const std::string& arraySignature, v8::Local<v8::Value>& value);
2019

2120
private:
22-
v8::Local<v8::Value> CheckForArrayAccessException(JEnv& env, const std::string& elementSignature, const void *value);
21+
v8::Local<v8::Value> ConvertToJsValue(JEnv& env, const std::string& elementSignature, const void *value);
2322

2423
JavaVM *jvm;
2524

0 commit comments

Comments
 (0)