RxSwift Hooks — a look into Reactive global error handling

Error handling is awesome. Error handling is necessary. Error handling can become painful, can make you cry and can cause a lot of headaches. But you can overcome it all. Hooks in RxSwift is a great tool to leave all this pain behind. It’s powerful and wholesome. Also, underused.
But we’re here to change that!

Individual error handling is pretty straightforward in RxSwift as it provides a variety of options to choose from. Most of you are familiar with the following:

.flatMap { [unowned self] _ in self.login() }
.subscribe(onError: { [weak self] error in
if error is LoginError {
.disposed(by: bag)
.flatMap { [unowned self] _ in self.login() }
.do(onError: { [weak self] error in
if error is CustomError {
.disposed(by: bag)

These two approaches will produce the same result by handling each of their cases individually. But what if there is a way to handle all of these cases in one place? Because always writing out onError seems quite counterproductive, right?

What is “Hooks”?

No, not this one! :)

Hooks offers a default error handling mechanism with a static interface for cases when you don’t provide your own onError handler.

Hooks will apply throughout your whole application where error handling is missing, all errors generated by any stream will pass through here. So you could show an alert, for example.

But let’s pump the brakes here, because there’s a catch in my last proposal. Figuratively and literally. There’s an important distinction between handling errors e.g: subscribe(onError: ), catchError. and handling errors as a side effect e.g: do(onError: ). In case of they’re being handled as a side effect, they’ll make their ways to the Hooks handler, while if you’re managing through catchError or subscribe(onError: ) that wouldn’t be the case.

Another important part here is the recordCardStackOnError. It will make sure you get a detailed call stack, making it much easier to trace and locate the source of errors as well. You should see something like this:

Hooks.recordCardStackOnError = true

I made a simple app to show you the difference between case by case error handling and general error handling. The sample application has three buttons:

The Login button doesn’t define any local error handling logic, and by not doing so, it’ll be handled by Hooks.

As I’ve mentioned before the middle button has a defined handling method, and it’s not managed as a side effect; therefore, you’re greeted with a custom error alert.

Last but not least, the Do button, which has implemented error handling, BUT only as a side effect, therefore it’ll reach the general Hooks.

Now let’s examine the ViewController!


As you can see here, the Subscribe button has its own error handling context, we’re checking if the caught error is a particular type, in our case CustomError, then we‘ll show an alert view.

Now let’s take a look at our Hooks implementation:


Here, we’re enabling call stack recording and setting up the default error handler. Moreover, we’re checking if the generated error is a specific GeneralError and if that’s the case, we’ll present the user with another alert.


I think that Hooks is a really powerful and hands-on tool. It makes the developer’s life a whole lot easier by streamlining error handling. This is especially important in the case of modularised projects, where things could quickly get out of hand. Furthermore, if you would like to send logs to any other logging service, such as Firebase, thanks to it, there’s no need to import that dependency into every module of your application. Another use case would be to use it for network errors and if there’s a need to handle individual scenarios, you’ll have the local context to do so without losing sight of the bigger picture.

You can check out and play with the example repo here:

At Supercharge, we are a next-generation innovation partner working with our clients to create transformative digital solutions. If you liked this article, check out some of Supercharge’s other articles on our blog, and follow us on LinkedIn, and Facebook. If you’re interested in open positions, follow this link.




As innovation partners, Supercharge works with clients to create transformative digital solutions. We create digital strategies, design delightful interfaces and build robust software. We are happy to share with you what we learn on this journey.

Recommended from Medium

3 Effective Java Features You Should Know

ResearchCoin’s tokenomics

A Measure of Linear Relationship

Avoiding the On-Screen Keyboard in Flutter

How to Operate a Planning Strategy for Your Business

How to Operate a Planning Strategy for Your Business

Pickle Rick — TryHackMe Writeup

Using Jidoka to Solve Process Problems

Using Jidoka to Solve Problems — abstract illustration

CMD Commands for Everyone

A picture of the command prompt for Linux.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Barczi Bálint

Barczi Bálint

“Whenever you find yourself on the side of the majority, it is time to pause and reflect” — Mark Twain

More from Medium

Open Source at Microsoft Mobile

Introducing Mobile Multi-platform to a Native Pod

Introduction to Kotlin Multiplatform Mobile — Getting Started

Handling Concurrency with Async Await in Swift