Description
Let's compare error handling in RxJS and Kefir:
RxJS. Example 1
import {Observable as O} from "rxjs"
O.from([1, 2, 3]).map(() => {
return x.y
}).subscribe(
(x) => console.log("x:", x),
(e) => console.log("e:", e),
)
e: ReferenceError: x is not defined
at MapSubscriber.project (/Users/ivankleshnin/Sandboxes/rxreact/ex1.rxjs.js:4:10)
Kefir. Example 1
import K from "kefir"
K.sequentially(100, [1, 2, 3]).map(() => {
return x.y
}).observe(
(x) => console.log("x:", x),
(e) => console.log("e:", e),
)
ReferenceError: x is not defined
at /Users/ivankleshnin/Sandboxes/rxreact/ex1.kefir.js:4:10
As we see, RxJS mixes operational and syntax errors which I consider a very bad idea.
Both end up being handled in the same function. Kefir separates two error types. Only operational errors will be caught and handled by our custom (e) => ...
lambda.
At least, both libraries show us the correct file, line and column.
Now let's take a look at Promise based streams:
RxJS. Example 2
import A from "axios"
import {Observable as O} from "rxjs"
O.fromPromise(A.get("http://localhost:8080/api/users/")).map(() => {
return x.y
}).subscribe(
(x) => console.log("x:", x),
(e) => console.log("e:", e),
)
e: ReferenceError: x is not defined
at MapSubscriber.project (/Users/ivankleshnin/Sandboxes/rxreact/ex2.rxjs.js:5:10)
The same behavior as in Example 1.
Kefir. Example 2
import A from "axios"
import K from "kefir"
K.fromPromise(A.get("http://localhost:8080/api/users/")).map(() => {
return x.y
}).observe(
(x) => console.log("x:", x),
(e) => console.log("e:", e),
)
(node:4313) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): ReferenceError: x is not defined
(node:4313) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Now this one is broken. Kefir looses an error stack trace and the cause of our syntax error is lost.
For some reason, the promise "sucked" the error in. It's neither handled by error handler like in RxJS, nor escaped to the process like previously 😞 As a consequence, any promise-based stream in Kefir is a hell to debug right now.
I expected to get a process crash from sync errors in both Kefir examples.