summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2017-06-19 21:26:59 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2017-06-19 21:26:59 -0300
commit8f95d71f0deb00e35f7d965c8e17694c42bc197a (patch)
tree497cfd0b93151be96f6d2a939ec28781c671b289
parentc6660adea2551d6a585bab264dc9d405f52b935c (diff)
downloadefl-8f95d71f0deb00e35f7d965c8e17694c42bc197a.tar.gz
mono: Support error handling on events
If an exception occurs in a managed callback, the exception is caught and the error reported to the stderr throught eina.Log.Error. An eina error is set to be raised when the code comes back to the managed side.
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh18
-rw-r--r--src/tests/efl_mono/Errors.cs21
2 files changed, 35 insertions, 4 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index 42fa18f699..89fbf6c568 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -479,7 +479,7 @@ struct klass
return true;
if (!as_generator(scope_tab << "private readonly object eventLock = new object();\n"
- << scope_tab << "Dictionary<string, int> event_cb_count = new Dictionary<string, int>();\n")
+ << scope_tab << "private Dictionary<string, int> event_cb_count = new Dictionary<string, int>();\n")
.generate(sink, NULL, context))
return false;
@@ -496,6 +496,7 @@ struct klass
<< scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error(\"Failed to add event proxy for event ${key}\");\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n"
<< scope_tab << scope_tab << scope_tab << "}\n"
+ << scope_tab << scope_tab << scope_tab << "eina.Error.RaiseIfOcurred();\n"
<< scope_tab << scope_tab << "} \n"
<< scope_tab << scope_tab << "event_cb_count[key]++;\n"
<< scope_tab << scope_tab << "return true;\n"
@@ -511,6 +512,7 @@ struct klass
<< scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error(\"Failed to remove event proxy for event ${key}\");\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n"
<< scope_tab << scope_tab << scope_tab << "}\n"
+ << scope_tab << scope_tab << scope_tab << "eina.Error.RaiseIfOcurred();\n"
<< scope_tab << scope_tab << "} else if (event_count == 0) {\n"
<< scope_tab << scope_tab << scope_tab << "eina.Log.Error(\"Trying to remove proxy for event ${key} when there is nothing registered.\");\n"
<< scope_tab << scope_tab << scope_tab << "return false;\n"
@@ -562,7 +564,12 @@ struct klass
<< scope_tab << "public void on_" << event_name << "_NativeCallback(System.IntPtr data, ref efl.Event evt)\n"
<< scope_tab << "{\n"
<< scope_tab << event_args
- << scope_tab << scope_tab << "On_" << event_name << "(args);\n"
+ << scope_tab << scope_tab << "try {\n"
+ << scope_tab << scope_tab << scope_tab << "On_" << event_name << "(args);\n"
+ << scope_tab << scope_tab << "} catch (Exception e) {\n"
+ << scope_tab << scope_tab << scope_tab << "eina.Log.Error(e.Message);\n"
+ << scope_tab << scope_tab << scope_tab << "eina.Error.Set(eina.Error.EFL_ERROR);\n"
+ << scope_tab << scope_tab << "}\n"
<< scope_tab << "}\n"
<< scope_tab << "efl.Event_Cb evt_" << event_name << "_delegate;\n"
<< scope_tab << "event EventHandler" << wrapper_args_template << " " << cls.cxx_name << "." << upper_name << "{\n")
@@ -644,7 +651,12 @@ struct klass
<< scope_tab << "protected void on_" << wrapper_evt_name << "_NativeCallback(System.IntPtr data, ref efl.Event evt)"
<< scope_tab << "{\n"
<< scope_tab << event_args
- << scope_tab << scope_tab << "On_" << wrapper_evt_name << "(args);\n"
+ << scope_tab << scope_tab << "try {\n"
+ << scope_tab << scope_tab << scope_tab << "On_" << wrapper_evt_name << "(args);\n"
+ << scope_tab << scope_tab << "} catch (Exception e) {\n"
+ << scope_tab << scope_tab << scope_tab << "eina.Log.Error(e.Message);\n"
+ << scope_tab << scope_tab << scope_tab << "eina.Error.Set(eina.Error.EFL_ERROR);\n"
+ << scope_tab << scope_tab << "}\n"
<< scope_tab << "}\n"
<< scope_tab << "event EventHandler" << wrapper_args_template << " " << *(lower_case[string] << ".") << klass.cxx_name << ".")
.generate(sink, escape_namespace(klass.namespaces), context))
diff --git a/src/tests/efl_mono/Errors.cs b/src/tests/efl_mono/Errors.cs
index 042e4ae0e4..c8c05a7afa 100644
--- a/src/tests/efl_mono/Errors.cs
+++ b/src/tests/efl_mono/Errors.cs
@@ -94,6 +94,25 @@ class TestEolianError
}
// events
- // virtual callbacks
+ class Listener
+ {
+ public bool called = false;
+ public void callback(object sender, EventArgs e) {
+ throw (new CustomException("Event exception"));
+ }
+ public void another_callback(object sender, EventArgs e) {}
+ }
+
+ public static void eina_error_event_raise_exception()
+ {
+ // An event whose managed delegate generates an exception
+ // must set an eina_error so it can be reported back to
+ // the managed code
+ efl.Loop loop = new efl.LoopConcrete();
+ Listener listener = new Listener();
+ loop.CALLBACK_ADD += listener.callback;
+
+ Test.AssertRaises<efl.EflException>(() => loop.IDLE += listener.another_callback);
+ }
}
}