Scala-js: Map StackTraceElement to their scala counterpart

Created on 3 Mar 2017  路  7Comments  路  Source: scala-js/scala-js

When throwing exceptions the stack is from the javascript environment. I'm more interested about the stack from the Scala point of view.

For example:

/* 01 */  import scala.scalajs.js.JSApp
/* 02 */  import scala.scalajs.js.annotation.JSExport
/* 03 */  
/* 04 */  object Main extends JSApp {
/* 05 */    @JSExport
/* 06 */    override def main(): Unit = {
/* 07 */      try {
/* 08 */        throw new Exception("Boom")
/* 09 */      } catch {
/* 10 */        case e: Exception => {
/* 11 */          e.printStackTrace()
/* 12 */        }
/* 13 */      }
/* 14 */   }
/* 15 */  }
java.lang.Exception: Boom
  at $c_jl_Exception.$c_jl_Throwable.fillInStackTrace__jl_Throwable(/home/gui/exceptions/target/scala-2.12/exceptions-fastopt.js:3041:14)
  at $c_jl_Exception.$c_jl_Throwable.init___T__jl_Throwable(/home/gui/exceptions/target/scala-2.12/exceptions-fastopt.js:3140:8)
  at java.lang.Exception.<init>(/home/gui/exceptions/target/scala-2.12/exceptions-fastopt.js:3596:52)
  at Main$.main(/home/gui/exceptions/target/scala-2.12/exceptions-fastopt.js:2869:95)
  at Main$.$$js$exported$meth$main(/home/gui/exceptions/target/scala-2.12/exceptions-fastopt.js:2881:8)
  at Main$.main(/home/gui/exceptions/target/scala-2.12/exceptions-fastopt.js:2884:15)
  at {anonymous}()([stdin]:40:66)
  at ContextifyScript.Script.runInThisContext(vm.js:25:33)
  at Object.exports.runInThisContext(vm.js:77:17)
  at {anonymous}()([stdin]-wrapper:6:22)

There is probably a way to find this information from the sourcemap.

question

Most helpful comment

What JS environment are you running in? If you install source map support in Node.js, it should resolve the stacktraces. See the tutorial for details.

All 7 comments

What JS environment are you running in? If you install source map support in Node.js, it should resolve the stacktraces. See the tutorial for details.

@gzm0 Oh I see.

Here I evaluate it in sbt with run. So it's the default environment. But I want to make this work in the browser for Scastie. I'm currently running the Scala.js output with js.eval.

So if I setup source map correctly I will get a Scala stack trace ?

Whether the stack trace gets resolved depends on your execution environment. There are two principal ways how to get your stack traces resolved:

The execution environment / JS VM does it for you.

This is the case in Node.js, since we explicitly request it in the runner if source map support is available.

This is probably also the case in your favorite browser supporting source maps.

In this case, Scala.js does not do anything. The stack-traces we get from the JS VM in the exception already point to Scala files.

You define your own source mapper from the environment

You can define it in the __ScalaJSEnv variable (see the doc). In this case, we feed the stack trace we get from the JS VM to that function before doing anything else with it. Whatever the function returns is what we then use to construct the Java-style stack traces.

How this applies to your problem

Not at all. I have not heard of a way to re-attach source maps to calls from eval. I guess the only chance you have is to execute the JavaScript by inserting a <script> tag into the page referencing a file on your server. But even then, it is entirely up to the browser of whomever is using Scastie to resolve the source maps (FF and Chrome manage IIRC).

Is there a concrete problem that needs fixing in this repo? Otherwise we should close this issue.

@sjrd The source map is setup but there is no stacktrace.

https://scastie.scala-lang.org/MasseGuillaume/rZlm4oStS7yExIXsrWF8QQ

Here the stacktrace shows:

java.lang.Exception: Boom
  at $c_jl_Exception.$c_jl_Throwable.fillInStackTrace__jl_Throwable(https://scastie.scala-lang.org/scalajs/MasseGuillaume/rZlm4oStS7yExIXsrWF8QQ/0/fastopt.js:10135:14)
  at $c_jl_Exception.$c_jl_Throwable.init___T__jl_Throwable(https://scastie.scala-lang.org/scalajs/MasseGuillaume/rZlm4oStS7yExIXsrWF8QQ/0/fastopt.js:10157:8)
  at java.lang.Exception.<init>(https://scastie.scala-lang.org/scalajs/MasseGuillaume/rZlm4oStS7yExIXsrWF8QQ/0/fastopt.js:12668:52)
  at Playground.<init>(https://scastie.scala-lang.org/scalajs/MasseGuillaume/rZlm4oStS7yExIXsrWF8QQ/0/fastopt.js:8478:93)
  at Main.<init>(https://scastie.scala-lang.org/scalajs/MasseGuillaume/rZlm4oStS7yExIXsrWF8QQ/0/fastopt.js:1881:38)
  at $e.Main(https://scastie.scala-lang.org/scalajs/MasseGuillaume/rZlm4oStS7yExIXsrWF8QQ/0/fastopt.js:1961:30)
  at {anonymous}()(<anonymous>:2:14)
  at vN(https://scastie.scala-lang.org/assets/client-opt.js:801:481)
  at HTMLScriptElement.<anonymous>(https://scastie.scala-lang.org/assets/client-opt.js:1582:207)

Oh I see, I need to serve sources too.
The source map points to the sbt runner: file:///tmp/scastie6228565359508348901/src/main/scala/main.scala
Is there a way to remap to a resource I can serve?
for example
https://scastie.scala-lang.org/MasseGuillaume/rZlm4oStS7yExIXsrWF8QQ/main.scala

I guess I can use -P:scalajs:mapSourceURI:source->dest to set this up. I will close this issue. I did not try if it work yet but it look like the right way to do it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sjrd picture sjrd  路  6Comments

lihaoyi picture lihaoyi  路  8Comments

dwijnand picture dwijnand  路  3Comments

japgolly picture japgolly  路  7Comments

japgolly picture japgolly  路  4Comments