Author: jsdelfino
Date: Sun Nov 12 17:32:32 2006
New Revision: 474110
URL: http://svn.apache.org/viewvc?view=rev&rev=474110
Log:
Improve error reporting with Ruby components. Catch ruby exceptions and turn
them into proper ServiceInvocationExceptions
Modified:
incubator/tuscany/cpp/sca/runtime/extensions/ruby/src/tuscany/sca/ruby/RubyServiceWrapper.cpp
Modified:
incubator/tuscany/cpp/sca/runtime/extensions/ruby/src/tuscany/sca/ruby/RubyServiceWrapper.cpp
URL:
http://svn.apache.org/viewvc/incubator/tuscany/cpp/sca/runtime/extensions/ruby/src/tuscany/sca/ruby/RubyServiceWrapper.cpp?view=diff&rev=474110&r1=474109&r2=474110
==============================================================================
---
incubator/tuscany/cpp/sca/runtime/extensions/ruby/src/tuscany/sca/ruby/RubyServiceWrapper.cpp
(original)
+++
incubator/tuscany/cpp/sca/runtime/extensions/ruby/src/tuscany/sca/ruby/RubyServiceWrapper.cpp
Sun Nov 12 17:32:32 2006
@@ -38,8 +38,38 @@
#include "tuscany/sca/ruby/RubyServiceProxy.h"
#include "commonj/sdo/SDO.h"
+#include <sstream>
+
using commonj::sdo::PropertyList;
+extern "C"
+{
+
+ typedef struct _safe_rb_call
+ {
+ VALUE instance;
+ ID method;
+ int argc;
+ const VALUE* argv;
+ } safe_rb_call;
+
+ static VALUE safe_rb_funcall(VALUE value)
+ {
+ safe_rb_call* call = (safe_rb_call*)value;
+ if (call->argc == 0)
+ {
+ VALUE result = rb_funcall(call->instance, call->method, 0);
+ return result;
+ }
+ else
+ {
+ VALUE result = rb_funcall2(call->instance, call->method,
call->argc, call->argv);
+ return result;
+ }
+ }
+
+}
+
namespace tuscany
{
namespace sca
@@ -235,14 +265,36 @@
// Invoke the specified method
- VALUE result;
- if (n == 0)
- {
- result = rb_funcall(instance, method, 0);
- }
- else
+ safe_rb_call call;
+ call.instance = instance;
+ call.method = method;
+ call.argc = n;
+ call.argv = args;
+ int error = 0;
+ VALUE result = rb_protect(safe_rb_funcall, (VALUE)&call,
&error);
+ if (error)
{
- result = rb_funcall2(instance, method, n, args);
+ // Convert a Ruby error to a C++ exception
+ VALUE lasterr = rb_gv_get("$!");
+ ostringstream msg;
+
+ // class
+ VALUE klass = rb_class_path(CLASS_OF(lasterr));
+ msg << "Ruby Exception " << RSTRING(klass)->ptr << ":
";
+
+ // message
+ VALUE message = rb_obj_as_string(lasterr);
+ msg << RSTRING(message)->ptr << endl;
+
+ // backtrace
+ if(!NIL_P(ruby_errinfo)) {
+ VALUE ary = rb_funcall(ruby_errinfo,
rb_intern("backtrace"), 0);
+ int c;
+ for (c=0; c<RARRAY(ary)->len; c++) {
+ msg << "from " <<
RSTRING(RARRAY(ary)->ptr[c])->ptr << endl;
+ }
+ }
+ throwException(ServiceInvocationException,
msg.str().c_str());
}
// Convert the Ruby result value to a C++ result
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]