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: opal -c with stdin stopped working
- Bug: const_defined? doesn't work properly with submodules
- Check zlib potential infinite loop HOT 1
- Bug: opal-repl with Chrome runner stopped working HOT 2
- Reminder: update top level 'source-map' used by linter
- Code duplication between stdlib/{nodejs,deno}/file.rb HOT 1
- Code duplication between chrome and firefox CDP runners
- Bug: file paths not included in ARGV when using `-e` HOT 1
- Bug: Wrong order of (JS) requires with prefork
- Bug: kwrestarg (**kwargs) doesn't support non-String (Symbol) keys HOT 3
- Feature: CLI tool --no-headless option
- Bug: Cannot rescue regexp syntax error
- don't use javascript block.length to determine number of arguments in block definition
- Bug: Minus signs of number literals missing (e.g. -1 => 1) if comment contains umlaut (e.g. "ΓΌ") HOT 5
- Feature: Opalfile
- Bug: Methods defined by `Module#define_method` with UnboundMethod do not accept a block
- 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
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.