JBCP
JBCP

Reputation: 13485

In RxJS, how can you get the value that caused an error?

Inside a .catch(), how can I find the value that caused the error?

For example, lets say you have code like this:

Rx.Observable.of(42)
.map((val) => {
  throw new Error('oops!');
})
.catch((err) => {
  // how can I get `42` here?
});

How can you know what ended up causing the error?

For bonus points, is this possibly in .finally()?

Upvotes: 3

Views: 365

Answers (1)

user3743222
user3743222

Reputation: 18665

If you want the value, pass it in your exception.

Rx.Observable.of(42)
.map((val) => {
  throw new AppError({message : 'oops!', contextInfo : {someName: 42}});
})
.catch((err) => {
  // get it from the `err` object
});

This requires that you implement your own kind of error (AppError) which inherits from the native Error. This technique is not specific to Rxjs but can be applied everywhere. Error is an object, to which you can add any field you see fit through inheritance. It is a good practice to have errors include any relevant info about the when(tracing)/where(blame assignment)/why(diagnostic) aspects of the error.

About how to create your own error, have a look at Custom_Error_Types.

finally operator uses a selector function which does not take any arguments. Hence, if it is possible to do this in finally, it will not be through parameter passing. You might still be able to do it through closure, but that is far from being something I would recommend.

UPDATE Referring to How can you know what ended up causing the error?, in the general case you can't. Just like with promises, errors are propagated up to where they are caught, or else end up bubbling out of the promise/observable context. So the usual techniques apply, the fail fast technique being the most productive :

  • fail fast : use a type system (of your own, provided by your language or else) - that way you will ensure you only handle values of the expected type, so you can eliminate those types of errors. I experimented with a babel plugin for contracts and I found it quite usable if you already use babel.
  • fail fast : catch error as early as you can, the farther you are from the source of the errors, the harder it is to investigate.
  • fail fast : use libraries that have good error reporting over those who don't (silent swallowing of errors is your enemy here). Good library will offer a configuration parameter for that purpose.
  • check the stack trace (with rxjs 5, it became easier to do this, but you still have to know about the internals)
  • add tracing/logging information to your code, etc.

Upvotes: 2

Related Questions