Advanced Asynchronous JavaScript

Catching Specific Errors

Advanced Asynchronous JavaScript

Check out a free preview of the full Advanced Asynchronous JavaScript course

The "Catching Specific Errors" Lesson is part of the full, Advanced Asynchronous JavaScript course featured in this preview video. Here's what you'd learn in this lesson:

Jafar discusses how to throw an error and catch specific errors with observables.


Transcript from the "Catching Specific Errors" Lesson

>> Jafar Husain: Does everybody get retry and how that worked? Notice we got some state, but it's all stored inside of operators. As we notice, when we were building up expressions, like we did with animations allowed, notice how many lets do we see in this code?
>> Jafar Husain: How many assignments, how much mutation do we see?

Nothing, right? That's how I like it. All right, it's very, very easy to understand things that don't change, especially when you have six, or seven, or nine things happening all at the same time, all trying to change the same variable. Most of us, certainly I'm not smart enough to understand that program most of the time.

Cool, so I think we talked about error handling, catch is a very, very, often if you wanna handle an error, maybe do something with it. Actually, there is an interesting pattern, we talked about try catch, we talked about doing this,
>> Jafar Husain: Right? But that's not the only thing you do in functions.

Sometimes you catch an error and you throw a more specific error. So how would we do that in observable, right? So how would we do,
>> Jafar Husain: What's the observable equivalent of this? It's totally a legitimate thing to do, just as legitimate in async programming as it is in synchronous programming.

>> Jafar Husain: In fact, honestly it's a really good exercise to ask yourself, hey, what would I do if this was just a function and synchronous code? What would I do? How would I handle this error and then slavishly transform that in to the asynchronous equivalent? Because observable is really just about push versus pull.

Everything else is orthogonal. How you design your function, what your functions do, what the signatures are. Other than the push and pull, it's really about the exact, you wanna be doing the exact same thing. So how would we do this using either the catch or the retry operator that we learned?

>> Jafar Husain: So let's say instead of filter being, instead of just catching it and suppressing it, we wanted to throw another error, special error, anybody have an idea?
>> Speaker 2: Let's wing it, throw operator?
>> Jafar Husain: You could actually do this, because the reality is RX catches any errors thrown from functions and then onerrors them, so that would work.

I think it's a little bit more declarative to just do this.
>> Jafar Husain: So Observable.error will create a stream that's just errors. And then that onerror will surface all the way through. Now, notice we were able to accept the real error because it comes into the function, and then wrap some error inside of that error.

And then I also saw somebody comment, is promises good for back-end work? If you're running a Node server, for example, yeah, for the most part, promises are just fine. Because in general on a server, you don't cancel, you timeout, right? When somebody's kicked off a request to a server, at least when you're handling an incoming request, right, there's rarely a good reason to cancel because.

But once someone's dispatched an HTTP request to you, how would they even cancel it, right? And so in those cases, I find async/await and promises great. Probably still not gonna talk about them today cuz this class is front-end masters, and so it's got a very front-end focus in this class that I wanna stay on.

But if you're doing Node programming, I think async/await and promises are great for a lot of those cases.
>> Speaker 2: Is the same true if you're using WebSockets on the back-end?
>> Jafar Husain: WebSockets, I probably wouldn't use promises for because they're scalar. So you can only get one result from a promise.

Whereas in general, if you're using something like WebSockets, observables are a better fit for that. There's also something called asynchronous iterators. Is anyone familiar with those?
>> Speaker 2: That's where my question was with the TC39 proposal.
>> Jafar Husain: Yeah, there's an upcoming type called asynchronous iterator that's making its way through the process right now.

And it's kinda what it sounds like, it's basically an iterator of promises, sort of generator of promises, if you're familiar with that. And in general, those are pretty good abstraction to use for IO, like if I'm reading from a file. What's nice about an iterator of promises, where I say, hey, give me the next value, and the producer gives me a promise instead of giving me the value, is that you have natural back pressure.

And what I mean when I say back pressure is look, if I don't want another value, if I'm not ready to process another value, I just wait, I don't call next, right? An observable doesn't have back pressure. It doesn't particularly care if you're ready to process a value or not cuz it's a push, right?

It's only just gonna push you a value as soon as the producer wants to push you a value. But an asynchronous integrator, much like an integrator, puts the consumer back in control, the consumer doesn't request a new value until they call next. And so asynchronous iterators are probably a good fit for WebSockets or IO streams.

Whereas something like an event, where there is really no concept of back pressure, you can't tell the user to wait to click, an observable is a better fit for that. But all three of them, you'll notice, have very similar operators, map, filter. In fact, all operators can be implemented on all of them, as a matter of fact.

So where were we, we were talking about,
>> Jafar Husain: I think we covered retry. I think we've actually pretty thoroughly covered error handling now. You can do all the same things you can do with try catch, you can do with observable and function composition. So you can just catch an error and return observable.empty to ignore it.

Or you can catch an error and return a new error inside of an observable.error, and that's how you transform an error into another error. And finally, the retry is a much more like high level primitive for a very common case like network requests. And it's something you can do, because we're, that you can't do with promises.

Cool, so hopefully that brings full circle the conversation around laziness, and we see the power of laziness.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now