Make stack traces more useful
See original GitHub issueRxJS version: 5.4.0 Code to reproduce:
const { Observable } = require('rxjs');
function myBigActionChainBuilder(){
//handle requests from the server, routing them to handlers in
//different files depending on what url we are serving.
return Observable.of({})
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => { return; })
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => Observable.of(state))
.mergeMap((state) => Observable.of(state))
}
myBigActionChainBuilder().subscribe(()=>{
//do nothing
})
Feature Request:
When I run the above code, it gives me this error, which is expected.
TypeError: You provided ‘undefined’ where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
But the stack trace, even if I insert Error.stackTraceLimit = Number.MAX_SAFE_INTEGER;
, only gives me the stack trace to my subscribe call. This is useless, as everyone has acknowledged, but I am surprised that no one has come up with an alternative. Therefore I would like to propose the solution that has worked very well for me.
Simply add this line to the Observable constructor this.conStack = new Error().stack;
, and change the subscribe method so it looks like the below.
subscribe(observerOrNext, error, complete) {
var operator = this.operator;
var sink = toSubscriber(observerOrNext, error, complete);
//add this:
if (sink) {
const myErr = sink.error;
const self = this;
sink.error = function (err) {
console.log('Observable error', err.message, self.conStack);
return myErr.apply(this, arguments);
}
}
//to here
... the rest of subscribe ...
This returns a much more useful stack trace that points to the actual operator call where the error was thrown. Here is an example stack trace from different code than the one above. As you can see the 4th item in the trace is the method that caused the error.
Observable error You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. Error
at new Observable (...\Rx.js:858:29)
at ScalarObservable.Observable.lift (...\Rx.js:871:33)
at ScalarObservable.switchMap (...\Rx.js:13299:21)
at $tw.boot.startup (...\boot.js:2125:27)
at \boot.js:2434:12
at $tw.boot.decryptEncryptedTiddlers (...\boot.js:1468:2)
at $tw.boot.boot [as boot] (...\boot.js:2432:11)
at Object.<anonymous> (...\tiddlywiki.js:13:10)
Issue Analytics
- State:
- Created 6 years ago
- Reactions:7
- Comments:11 (3 by maintainers)
According to the docs of rxjs v7 a goal is to make stack traces shorter. Could any of the implementers shed some light on how they want to achieve this? I know of the trx-branch which seems promising. Is this the planned way to go?
Would it be possible to add a global variable of some sort that would allow this to be turned on or off?