3

I am using the new stacktracejs libary and it returns a promise.

StackTrace.get() // this results in a promise

Is there something I can do to make it synchronous?

like this:

var result = magicalSomething(StackTrace.get());
Eric Wendelin
  • 43,147
  • 9
  • 68
  • 92
dtracers
  • 1,534
  • 3
  • 17
  • 37
  • ES7 async/await (not really sync but very much sync-like). `let result = await StackTrace.get()` Or some generator based coroutine library. – Yury Tarabanko Jun 05 '16 at 20:04
  • I looked at this http://www.tivix.com/blog/making-promises-in-a-synchronous-manner/ But it was so confusing – dtracers Jun 05 '16 at 20:20
  • Why do you need it to be synchronous? – robertklep Jun 05 '16 at 20:31
  • 1
    If the original operation is asynchronous, there is NOTHING you can do to make it synchronous. Javascript does not work that way. You can use asynchronous code in order to use it properly. You cannot make it be synchronous. Even the ES7 async/await suggestion is not really synchronous (it just kind of makes it look that way). – jfriend00 Jun 05 '16 at 20:35
  • 1
    If you back up a few steps and show us the actual overall problem you're trying to solve, I'm quite sure folks here can show you a solution. But, the solution path you're pursuing now (making an async operation be synchronous) is a dead-end. Keep in mind, you are more likely to get a great answer to your question if you describe the actual problem rather than ask about your attempted solution. – jfriend00 Jun 05 '16 at 20:37
  • I will just use the old version of the library. It is very simple. I am trying to get the stack trace in a synchronous way. Even if it is not truly synchounous I need it to be in its "Thread" (i know js doesn't really have threads but it kinda does) – dtracers Jun 05 '16 at 21:26
  • @dtracers `var trace = new Error().stack` - tada, if that's all you need that is. – Benjamin Gruenbaum Jun 05 '16 at 21:32

3 Answers3

5

Update: there is now a .getSync() for stack traces, it gives partial information but you can use it.

StackTrace.js works by making calls to the script files involved in the stack trace and extracting additional information for them. This means that you cannot obtain the stack trace it generates since a part is already asynchronous.

Technically, this is in fact solvable and could be made synchronous (at the price of freezing the page for tens of seconds) - however that does not appear to be a design goal of the library.

Instead, use what the library offers and use the given promise:

StackTrace.get().then(function(result) {
   // I got result here
});
Community
  • 1
  • 1
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • Is there a way to use both versions (old and new) so that I can have a non upgraded stack strace synchronously that is then replaced with the new one? I use requirejs so idk if I can actually use both at the same time. – dtracers Jun 05 '16 at 21:40
  • 1
    That might not be a bad idea, you can go ahead and ask for it - but I feel like this is an x-y problem. Why can't you use the promise-returning version? If you have a compelling use case it would go a long way convincing library authors. – Benjamin Gruenbaum Jun 05 '16 at 21:50
  • I actually use exceptions like in java and so there will be some times where the exception can't really wait around for a trace to be grabbed bc you can't really tell the try catch to wait till all the promises are resolved – dtracers Jun 05 '16 at 21:59
  • @dtracers well, here is a cheat way to get a stack trace that's not as detailed but would generally work `var trace; try { throw new Error(); } catch (e) { trace = e.stack; }` - `trace` now contains the stack trace of the error which you can use - completely synchronous but won't give you information that's _as_ useful. – Benjamin Gruenbaum Jun 05 '16 at 22:09
  • Thanks I'll probably end up doing that and then replacing that result with the library's version. And hope that most of the time it gets replaced by the time it is needed. – dtracers Jun 05 '16 at 22:15
  • Thanks @BenjaminGruenbaum for updating. Updating to stacktrace-js v1.3+ and calling `.getSync()` is the correct answer now – Eric Wendelin Jul 07 '16 at 21:01
1

UPDATE: Benjamin's answer is more correct. Use this as of stacktrace.js v1.3.0

var stacktrace = StackTrace.getSync();

If you need synchronous behavior and don't care about guessing anonymous functions or source-map support or old IE, you can just use the stack parsing lib that underlies stacktrace.js - error-stack-parser this way:

function stacktrace() {
  try {
    throw new Error();
  } catch (e) {
    return ErrorStackParser.parse(e);
  }
}
Eric Wendelin
  • 43,147
  • 9
  • 68
  • 92
0

Just wanted to mention that it is also possible to synchronously get the source-mapped stack-trace, with the stacktrace-js library.

It's not part of the API, but it's possible with some modifications.

See here: https://github.com/stacktracejs/stacktrace.js/issues/188

Venryx
  • 15,624
  • 10
  • 70
  • 96