Skip to content

Commit df16e2a

Browse files
committed
better error handling
1 parent fc32367 commit df16e2a

3 files changed

Lines changed: 94 additions & 4 deletions

File tree

src/java.cpp

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,76 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
177177
}
178178

179179
/*static*/ v8::Handle<v8::Value> Java::callStaticMethod(const v8::Arguments& args) {
180-
// TODO: write me
180+
v8::HandleScope scope;
181+
Java* self = node::ObjectWrap::Unwrap<Java>(args.This());
182+
v8::Handle<v8::Value> ensureJvmResults = self->ensureJvm();
183+
if(!ensureJvmResults->IsUndefined()) {
184+
return ensureJvmResults;
185+
}
186+
JNIEnv* env = self->getJavaEnv();
187+
188+
int argsEnd = args.Length();
189+
190+
// argument - className
191+
if(args.Length() < 1 || !args[0]->IsString()) {
192+
return ThrowException(v8::Exception::TypeError(v8::String::New("Argument 0 must be a string")));
193+
}
194+
v8::Local<v8::String> classNameObj = v8::Local<v8::String>::Cast(args[0]);
195+
v8::String::AsciiValue classNameVal(classNameObj);
196+
std::string className = *classNameVal;
197+
198+
// argument - method name
199+
if(args.Length() < 2 || !args[1]->IsString()) {
200+
return ThrowException(v8::Exception::TypeError(v8::String::New("Argument 1 must be a string")));
201+
}
202+
v8::Local<v8::String> methodNameObj = v8::Local<v8::String>::Cast(args[1]);
203+
v8::String::AsciiValue methodNameVal(methodNameObj);
204+
std::string methodName = *methodNameVal;
205+
206+
// argument - callback
207+
v8::Handle<v8::Value> callback;
208+
if(args[args.Length()-1]->IsFunction()) {
209+
callback = args[argsEnd-1];
210+
argsEnd--;
211+
} else {
212+
callback = v8::Null();
213+
}
214+
215+
// build args
216+
std::list<int> methodArgTypes;
217+
jarray methodArgs = v8ToJava(env, args, 2, argsEnd, &methodArgTypes);
218+
219+
// find class and method
220+
jclass clazz = javaFindClass(env, className);
221+
if(clazz == NULL) {
222+
std::ostringstream errStr;
223+
errStr << "Could not create class " << className.c_str();
224+
v8::Handle<v8::Value> error = javaExceptionToV8(env, errStr.str());
225+
226+
v8::Handle<v8::Value> argv[2];
227+
argv[0] = error;
228+
argv[1] = v8::Undefined();
229+
v8::Function::Cast(*callback)->Call(v8::Context::GetCurrent()->Global(), 2, argv);
230+
return v8::Undefined();
231+
}
232+
std::list<jobject> staticMethods = javaReflectionGetStaticMethods(env, clazz);
233+
jobject method = javaFindBestMatchingMethod(env, staticMethods, methodName.c_str(), methodArgTypes);
234+
if(method == NULL) {
235+
std::ostringstream errStr;
236+
errStr << "Could not find method \"" << methodName.c_str() << "\"";
237+
v8::Handle<v8::Value> error = javaExceptionToV8(env, errStr.str());
238+
239+
v8::Handle<v8::Value> argv[2];
240+
argv[0] = error;
241+
argv[1] = v8::Undefined();
242+
v8::Function::Cast(*callback)->Call(v8::Context::GetCurrent()->Global(), 2, argv);
243+
return v8::Undefined();
244+
}
245+
246+
// run
247+
StaticMethodCallBaton* baton = new StaticMethodCallBaton(self, clazz, method, methodArgs, callback);
248+
baton->run();
249+
181250
return v8::Undefined();
182251
}
183252

@@ -217,10 +286,15 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
217286
if(clazz == NULL) {
218287
std::ostringstream errStr;
219288
errStr << "Could not create class " << className.c_str();
220-
return javaExceptionToV8(env, errStr.str());
289+
return ThrowException(javaExceptionToV8(env, errStr.str()));
221290
}
222291
std::list<jobject> staticMethods = javaReflectionGetStaticMethods(env, clazz);
223292
jobject method = javaFindBestMatchingMethod(env, staticMethods, methodName.c_str(), methodArgTypes);
293+
if(method == NULL) {
294+
std::ostringstream errStr;
295+
errStr << "Could not find method \"" << methodName.c_str() << "\"";
296+
return ThrowException(javaExceptionToV8(env, errStr.str()));
297+
}
224298

225299
// run
226300
v8::Handle<v8::Value> callback = v8::Object::New();

src/utils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@ v8::Handle<v8::Value> javaExceptionToV8(JNIEnv* env, const std::string& alternat
179179
printf("BEGIN Java Exception -------\n");
180180
env->ExceptionDescribe(); // TODO: handle error
181181
printf("END Java Exception ---------\n");
182-
return ThrowException(v8::Exception::TypeError(v8::String::New("java exception")));
182+
return v8::Exception::TypeError(v8::String::New("java exception"));
183183
} else {
184-
return ThrowException(v8::Exception::TypeError(v8::String::New(alternateMessage.c_str())));
184+
return v8::Exception::TypeError(v8::String::New(alternateMessage.c_str()));
185185
}
186186
}

test/simple-test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@ exports['Simple'] = nodeunit.testCase({
2828
test.done();
2929
},
3030

31+
"test method does not exists (sync)": function(test) {
32+
test.throws(
33+
function() {
34+
java.callStaticMethodSync("java.lang.System", "badMethod");
35+
}
36+
);
37+
test.done();
38+
},
39+
40+
"test method does not exists (async)": function(test) {
41+
java.callStaticMethod("java.lang.System", "badMethod", function(err, result) {
42+
if(err) { test.done(); return; }
43+
test.done(new Error("should throw exception"));
44+
});
45+
},
46+
3147
"create an instance of a class and call methods (getName) (async)": function(test) {
3248
java.newInstance("java.util.ArrayList", function(err, list) {
3349
if(err) { console.log(err); return; }

0 commit comments

Comments
 (0)