forked from enlightenment/efl
eina-js: binding for Eina_Error added
It's a function that check if an error is set and convert to a JavaScript exception. The exception object is well specified and useful, giving sane information about the object and following a model similar to the one used by the Eina_Value binding.
This commit is contained in:
parent
8412ec8918
commit
f250ae0c47
|
@ -20,7 +20,8 @@ lib_eina_js_libeina_js_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
|
|||
|
||||
lib_eina_js_libeina_js_la_SOURCES = \
|
||||
bindings/eina_js/eina_js_container.cc \
|
||||
bindings/eina_js/eina_js_value.cc
|
||||
bindings/eina_js/eina_js_value.cc \
|
||||
bindings/eina_js/eina_js_error.cc
|
||||
|
||||
#installed_einacxxmainheadersdir = $(includedir)/eina-cxx-@VMAJ@
|
||||
#dist_installed_einacxxmainheaders_DATA = \
|
||||
|
@ -58,9 +59,11 @@ bindings/eina_cxx/eina_value.hh
|
|||
if EFL_ENABLE_TESTS
|
||||
|
||||
check_PROGRAMS += tests/eina_js/eina_js_suite \
|
||||
tests/eina_js/eina_js_value
|
||||
tests/eina_js/eina_js_value \
|
||||
tests/eina_js/eina_js_error
|
||||
TESTS += tests/eina_js/eina_js_suite \
|
||||
tests/eina_js/eina_js_value
|
||||
tests/eina_js/eina_js_value \
|
||||
tests/eina_js/eina_js_error
|
||||
|
||||
tests_eina_js_eina_js_suite_SOURCES = \
|
||||
tests/eina_js/eina_js_suite.cc
|
||||
|
@ -68,6 +71,9 @@ tests/eina_js/eina_js_suite.cc
|
|||
tests_eina_js_eina_js_value_SOURCES = \
|
||||
tests/eina_js/eina_js_value.cc
|
||||
|
||||
tests_eina_js_eina_js_error_SOURCES = \
|
||||
tests/eina_js/eina_js_error.cc
|
||||
|
||||
tests_eina_js_eina_js_suite_CXXFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-DTESTS_WD=\"`pwd`\" \
|
||||
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eina_js\" \
|
||||
|
@ -95,6 +101,19 @@ tests_eina_js_eina_js_value_CXXFLAGS = -I$(top_builddir)/src/lib/efl \
|
|||
tests_eina_js_eina_js_value_LDADD = @CHECK_LIBS@ @USE_EINA_JS_LIBS@ @USE_EINA_LIBS@ @USE_EO_LIBS@
|
||||
tests_eina_js_eina_js_value_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EINA_JS_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@
|
||||
|
||||
tests_eina_js_eina_js_error_CXXFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-DTESTS_WD=\"`pwd`\" \
|
||||
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eina_js\" \
|
||||
-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/eina_js\" \
|
||||
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eina_js\" \
|
||||
@CHECK_CFLAGS@ \
|
||||
@EINA_CXX_CFLAGS@ \
|
||||
@EO_CXX_CFLAGS@ \
|
||||
@EO_CFLAGS@ \
|
||||
@EINA_JS_CFLAGS@
|
||||
tests_eina_js_eina_js_error_LDADD = @CHECK_LIBS@ @USE_EINA_JS_LIBS@ @USE_EINA_LIBS@ @USE_EO_LIBS@
|
||||
tests_eina_js_eina_js_error_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EINA_JS_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <eina_js_error.hh>
|
||||
|
||||
namespace efl { namespace js {
|
||||
|
||||
EAPI
|
||||
void convert_error_to_javascript_exception(v8::Isolate *isolate)
|
||||
{
|
||||
using v8::Local;
|
||||
using v8::Object;
|
||||
using v8::String;
|
||||
|
||||
Eina_Error err = eina_error_get();
|
||||
if (!err)
|
||||
return;
|
||||
|
||||
Local<Object> je = Object::New(isolate);
|
||||
je->Set(String::NewFromUtf8(isolate, "code"),
|
||||
String::NewFromUtf8(isolate, "Eina_Error"));
|
||||
je->Set(String::NewFromUtf8(isolate, "value"),
|
||||
String::NewFromUtf8(isolate, eina_error_msg_get(err)));
|
||||
isolate->ThrowException(je);
|
||||
}
|
||||
|
||||
} } // namespace efl { namespace js {
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef EINA_JS_ERROR_HH
|
||||
#define EINA_JS_ERROR_HH
|
||||
|
||||
#include <v8.h>
|
||||
#include <Eina.hh>
|
||||
|
||||
namespace efl { namespace js {
|
||||
|
||||
/**
|
||||
* Converts the error value set through Eina's error tool to a JavaScript
|
||||
* exception.
|
||||
*
|
||||
* The exception object will have a `code` string field with the `"Eina_Error"`
|
||||
* string value and a `value` string field with the value extracted from
|
||||
* `eina_error_msg_get`.
|
||||
*
|
||||
* It won't reset the error to NULL, so you can still access the error object,
|
||||
* but if you keep calling this function without clearing the error, a new
|
||||
* exception will be generated for each call after some error is reached. We,
|
||||
* therefore, suggest you to call `eina_error_set(0)` afterwards.
|
||||
*/
|
||||
void convert_error_to_javascript_exception(v8::Isolate *isolate);
|
||||
|
||||
} } // namespace efl::js
|
||||
|
||||
#endif /* EINA_JS_ERROR_HH */
|
|
@ -0,0 +1,111 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
#include <eina_js_error.hh>
|
||||
#include <Eo.hh>
|
||||
|
||||
void print(const v8::FunctionCallbackInfo<v8::Value> &args)
|
||||
{
|
||||
bool first = true;
|
||||
for (int i = 0; i < args.Length(); i++) {
|
||||
v8::HandleScope handle_scope(args.GetIsolate());
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
printf(" ");
|
||||
}
|
||||
v8::String::Utf8Value str(args[i]);
|
||||
std::cout << std::string(*str, str.length());
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void clear_eina_error(const v8::FunctionCallbackInfo<v8::Value> &args)
|
||||
{
|
||||
eina_error_set(0);
|
||||
efl::js::convert_error_to_javascript_exception(args.GetIsolate());
|
||||
}
|
||||
|
||||
void set_eina_error(const v8::FunctionCallbackInfo<v8::Value> &args)
|
||||
{
|
||||
eina_error_set(eina_error_msg_static_register("foobar"));
|
||||
efl::js::convert_error_to_javascript_exception(args.GetIsolate());
|
||||
}
|
||||
|
||||
static const char script[] =
|
||||
"function assert(test, message) { if (test !== true) throw message; };"
|
||||
|
||||
"var captured = false;"
|
||||
"try {"
|
||||
" clear_eina_error();"
|
||||
"} catch(e) {"
|
||||
" captured = true;"
|
||||
"}"
|
||||
"assert(captured === false, '#1');"
|
||||
|
||||
"captured = false;"
|
||||
"try {"
|
||||
" set_eina_error();"
|
||||
"} catch(e) {"
|
||||
" assert(e.code === 'Eina_Error', '#2');"
|
||||
" assert(e.value === 'foobar', '#3');"
|
||||
" captured = true;"
|
||||
"}"
|
||||
"assert(captured === true, '#4');"
|
||||
;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
efl::eina::eina_init eina_init;
|
||||
efl::eo::eo_init eo_init;
|
||||
|
||||
v8::V8::Initialize();
|
||||
v8::V8::InitializeICU();
|
||||
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
|
||||
v8::Isolate* isolate = v8::Isolate::New();
|
||||
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Handle<v8::Context> context
|
||||
= v8::Context::New(isolate, NULL, v8::ObjectTemplate::New(isolate));
|
||||
|
||||
if (context.IsEmpty()) {
|
||||
fprintf(stderr, "Error creating context\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
{
|
||||
// Enter the execution environment before evaluating any code.
|
||||
v8::Context::Scope context_scope(context);
|
||||
v8::Handle<v8::Object> global = context->Global();
|
||||
|
||||
global->Set(v8::String::NewFromUtf8(isolate, "print"),
|
||||
v8::FunctionTemplate::New(isolate, print)->GetFunction());
|
||||
global->Set(v8::String::NewFromUtf8(isolate, "clear_eina_error"),
|
||||
v8::FunctionTemplate::New(isolate, clear_eina_error)
|
||||
->GetFunction());
|
||||
global->Set(v8::String::NewFromUtf8(isolate, "set_eina_error"),
|
||||
v8::FunctionTemplate::New(isolate, set_eina_error)
|
||||
->GetFunction());
|
||||
|
||||
{
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::TryCatch try_catch;
|
||||
auto source = v8::String::NewFromUtf8(isolate, script);
|
||||
v8::Handle<v8::Script> script = v8::Script::Compile(std::move(source));
|
||||
|
||||
assert(!script.IsEmpty());
|
||||
|
||||
/*v8::Handle<v8::Value> result = */script->Run();
|
||||
|
||||
if (try_catch.HasCaught()) {
|
||||
v8::String::Utf8Value message(try_catch.Message()->Get());
|
||||
std::cerr << std::string(*message, message.length()) << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue