Comments (6)
Might be a regression of #2296
from opal.
I think this is a bug in Firefox, not Opal... why:
My test case:
puts "Hello"
def a
1.times do
raise RuntimeError, "Boom!"
end
end
begin
a
rescue Exception => e
p `e.stack`
end
Then I run:
opal -Rgjs index.rb
(Note: gjs
is a GNOME (Linux) JavaScript runtime that uses Firefox JS engine, if you don't have it use server
).
Note that I specifically raise RuntimeError, because that's what's raised if no class is set.
A backtrace in e.stack
is set for classes that are either of Exception class or a direct descendant of Exception. So, for those classes it is set:
- StandardError
- ScriptError
- SystemExit
For those it's not set:
- SyntaxError
- RuntimeError
Perhaps we could work around that bug...
diff --git a/opal/corelib/error.rb b/opal/corelib/error.rb
index da74c1cea..9d6c24eb1 100644
--- a/opal/corelib/error.rb
+++ b/opal/corelib/error.rb
@@ -11,6 +11,10 @@ class ::Exception < `Error`
error.name = self.$$name;
error.message = message;
error.cause = #{$!};
+
+ // A bug in Firefox would not set a stack for non-direct descendants of Error
+ error.stack = (new Error).stack;
+
Opal.send(error, error.$initialize, args);
// Error.captureStackTrace() will use .name and .toString to build the
from opal.
Having tried to reproduce this in pure JavaScript, I think the issue goes deeper. My theory is that the stack
is set in Error
's constructor.
Consider this Opal code:
%x{
class Test {
constructor() {
console.log("Hello world!");
}
}
}
class Test < `Test`; end
Test.new
class Test2 < Test; end
Test2.new
class Test3 < Test2; end
Test3.new
class Test4 < Test3; end
Test4.new
The first class is bridged to (NOT subclassing) JavaScript Test. The next ones are subclassing it. We would expect the JS constructor to be called on each one, yet only the first two call it.
Let's try this patch:
diff --git a/opal/corelib/runtime.js b/opal/corelib/runtime.js
index 11671ac13..9dfda69e1 100644
--- a/opal/corelib/runtime.js
+++ b/opal/corelib/runtime.js
@@ -567,7 +567,7 @@
// @return new [Class] or existing ruby class
//
function $allocate_class(name, superclass, singleton) {
- var klass;
+ var klass, super_constructor;
if (superclass != null && superclass.$$bridge) {
// Inheritance from bridged classes requires
@@ -581,7 +581,9 @@
return self;
}
} else {
- klass = function(){};
+ klass = function() {
+ if (superclass) superclass.$$constructor(this, arguments);
+ };
}
if (name && name !== nil) {
Unfortunately, it doesn't fix the Firefox issue :(
from opal.
My theory was right (but code was wrong). I read more into $allocate_class
and comments describes precisely what's happening. A correct patch is as follows:
diff --git a/opal/corelib/runtime.js b/opal/corelib/runtime.js
index 11671ac13..301139d42 100644
--- a/opal/corelib/runtime.js
+++ b/opal/corelib/runtime.js
@@ -538,6 +538,13 @@
Opal.$$$ = Opal.const_get_qualified;
Opal.$r = Opal.const_get_relative_factory;
+ function descends_from_bridged_class(klass) {
+ if (klass == null) return false;
+ if (klass.$$bridge) return klass;
+ if (klass.$$super) return descends_from_bridged_class(klass.$$super);
+ return false;
+ }
+
// Modules & Classes
// -----------------
@@ -567,14 +574,14 @@
// @return new [Class] or existing ruby class
//
function $allocate_class(name, superclass, singleton) {
- var klass;
+ var klass, bridged_descendant;
- if (superclass != null && superclass.$$bridge) {
+ if (bridged_descendant = descends_from_bridged_class(superclass)) {
// Inheritance from bridged classes requires
// calling original JS constructors
klass = function() {
var args = $slice(arguments),
- self = new ($bind.apply(superclass.$$constructor, [null].concat(args)))();
+ self = new ($bind.apply(bridged_descendant.$$constructor, [null].concat(args)))();
// and replacing a __proto__ manually
$set_proto(self, klass.$$prototype);
from opal.
@elia I believe you could have encountered a similar issue while bridging the thing you were bridging...
from opal.
@hmdne yes! I ventured exactly in that area and this explains a couple of weird things I've seen
from opal.
Related Issues (20)
- Bug: jsid_cache breaks for `"toString"`, and I suspect other methods of JS Object HOT 6
- is it possible to require 'openssl' in opalrb? HOT 1
- is it possible to require 'openssl' in opalrb? HOT 1
- Bug: `def` + `define_method` + `return` cause `LocalJumpError` HOT 1
- Feature: mirror Opal only classes into CRuby
- Bug: define_method -> block -> return -- unexpected return
- Bug: String#strip differs in handling the NBSP character
- 1.8.2 release was not completed HOT 2
- Bug: `Hash#compare_by_identity` does not work with string keys
- Bug: Bad behaviour with combination of: StringScanner#scan, multiline regexp, multiple lines HOT 2
- Bug: String interpolation with bridged classes does not call `to_s` HOT 2
- Bug: Cannot run minitest on Ruby 3.3 HOT 1
- Feature: Date and DateTime classes from Ruby HOT 5
- Bug: `load` cannot be invoked on a path unless `require` has been called on it first
- Feature: `puts` & `p` can handle native JS objects not wrapped by `Native` for simple debugging/troubleshooting
- Rack, Roda, Sinatra and other framework compatibility (when running on Opal and Node or alternative)
- Feature: Interact with JS Object directly without having to manually wrap with Native HOT 1
- Bug: Segmentation fault when building with Opal::Builder#build_str HOT 6
- Feature: Allow use of CLI runners outside of CLI context
- Bug: Array include? returns true when == returns nil HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from opal.