Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala.js stacktraces

Tags:

scala.js

I'm frustrated by unintelligible stacktraces when my Scala.js code throws an exception. I thought I had a solution using a Javascript library (see Getting a scala stacktrace) but it breaks too often.

How do you extract meaning (where the program broke; how it got there -- in terms of the Scala code) from a stacktrace like the following. Or am I doing something wrong to even get an untranslated stacktrace?

Sample Scala.js stacktrace

like image 774
bwbecker Avatar asked Sep 07 '17 18:09

bwbecker


1 Answers

Take a look at this code I wrote a while back in my youi framework: https://github.com/outr/youi/tree/e66dc36a12780fa8941152d07de9c3a52d28fc10/app/js/src/main/scala/io/youi/app/sourceMap

It is used to reverse JS stack traces to Scala stack traces. In youi I send the errors to the server so I can monitor browser errors that occur with the complete traceback.

Brief Overview

  1. source-map.js

You need source-map.js to parse the js.map file that Scala.js generated when it compiled your code. See: https://github.com/mozilla/source-map

  1. Load the js.map file via Ajax

The SourceMapConsumer needs a js.Object (JSON) of the js.map file. See https://github.com/outr/youi/blob/e66dc36a12780fa8941152d07de9c3a52d28fc10/app/js/src/main/scala/io/youi/app/sourceMap/ErrorTrace.scala#L58 for an example of loading via youi's Ajax features.

  1. Process the Throwable

The trace represents line and columns in the JS file and you can pass that information to SourceMapConsumer to get the original Scala line numbers back (see SourceMapConsumer.originalPositionFor). See ErrorTrace.toCause (https://github.com/outr/youi/blob/e66dc36a12780fa8941152d07de9c3a52d28fc10/app/js/src/main/scala/io/youi/app/sourceMap/ErrorTrace.scala#L98) for an example iterating over the Throwable's trace elements.

  1. Handling Errors

Now that you have the capacity to process JavaScript errors and convert them back to Scala traces, you need to actually receive the errors. If you want to globally handle uncaught errors set a function to window.onerror to capture errors. As of this writing, the function signature in Scala.js isn't ideal for handling all information, so in youi I use js.Dynamic to set it to what I need (see: https://github.com/outr/youi/blob/e66dc36a12780fa8941152d07de9c3a52d28fc10/app/js/src/main/scala/io/youi/app/ClientApplication.scala#L35). Also, notice that in ErrorTrace it supports multiple incoming types of errors (ErrorEvent, Throwable, and a more generic scenario). This is because in JavaScript the errors come in different ways based on what's happening. This is a fairly complex topic, and why I created this functionality in youi to simplify things.

Not nearly as brief an overview as I would have liked, but this isn't a simple problem to solve. The source-map GitHub project (https://github.com/mozilla/source-map) has decent documentation and is what I used originally to write my solution (with some added trial and error). If the information I've provided is incomplete I'd recommend reading more there as it should provide the majority of information, and probably better explained.

like image 78
darkfrog Avatar answered Oct 06 '22 12:10

darkfrog