3

When my scala-js code throws an error, I'd like to send a sensible stacktrace back to my server to put in the logs. By "sensible stacktrace" I mean something that gives the Scala methods, filenames, and line numbers rather than the transpiled javascript code.

I've made good progress by getting the source map and using the Javascript source-map library (https://github.com/mozilla/source-map) to translate each element of the stacktrace from javascript to the corresponding Scala code.

My issue: I need the column number of the javascript code that threw the error but don't see how to obtain it. Printing a StackTraceElement gives a result similar to

oat.browser.views.query.QueryRunView$.renderParamsTable$1(https://localhost:9443/assets/browser-fastopt.js:34787:188)

I need the "188" at the end of the line but don't see how to get it other than calling toString and parsing the result. Looking at the StackTraceElement code, the column number is a private variable with nothing in the API to access it.

Is there another approach to this that I'm completely overlooking? Anything built into scala-js that converts a javascript stacktrace to a Scala stacktrace?

bwbecker
  • 1,031
  • 9
  • 21
  • Is this code available somewhere? I'd be interested in utilizing it myself. – darkfrog Mar 09 '17 at 16:49
  • I put up a gist at https://gist.github.com/bwbecker/e92324dc8875e10f44b5161c2515a186. Note that this is still a work in progress. My attention got diverted to other stuff, so the posted code is still pretty unpolished. If it's of use, great. Feedback more than welcome. – bwbecker Mar 14 '17 at 14:07

2 Answers2

2

There is nothing in the public API to access the column number because this is a Java API, and Scala.js cannot add public members to Java APIs.

To work around this issue in the case of StackTraceElement, we export getColumnNumber(): Int to JavaScript. You can therefore use the following code to retrieve the column number:

def columnNumberOfStackTraceElement(ste: StackTraceElement): Int =
  ste.asInstanceOf[js.Dynamic].getColumnNumber().asInstanceOf[Int]

Note that this "feature" is undocumented, and might change without notice in a future major version of Scala.js. If it disappears, it will be replaced by something reliable. In the meantime, the above should get you going.

sjrd
  • 21,805
  • 2
  • 61
  • 91
2

I subsequently found the StackTraceJS library which does what I needed. I combined a ScalaJS facade for it with a facade for JSNlog to come up with a package that meets my needs pretty well. See jsnlog-facade. It logs to the browser console and/or the server, with Scala stack traces. Demo code included.

bwbecker
  • 1,031
  • 9
  • 21