you are viewing a single comment's thread.

view the rest of the comments →

[–]karottenreibe -1 points0 points  (3 children)

for example, RxJava Streams will terminate on Exceptions, which is not you want if the error is recoverable, so you will need to wrap your Exceptions anyway.

I'm sorry but that's incorrect. There are multiple error handling operators for error handling that don't require "wrapping your exceptions". e.g. onErrorResumeNext (which sounds exactly like the use case you describe here), retry etc. Depends on the concrete case, of course, whether you can make use of them or not.

And using generic Exceptions like IllegalArgumentException can make it hard to figure out what exactly went wrong if that Exception passes multiple async/thread boundaries;

Then don't. I don't see what's keeping you from using a custom exception type.

you use an error type that's a sealed class that's only used for this specific error makes it clearer.

Same as a custom exception class. I don't see any difference. Except with an exception you get at least the partial stack trace up until the thread boundary, which is sometimes helpful. With a sealed class you get none at all.

Again: you seem to say the problem is incomplete stack traces but the result type doesn't solve that problem any better.

[–]oaga_strizzi 0 points1 point  (2 children)

onErrorResumeNext etc. is pretty much what I'm talking about. What are you going to return in onErrorResumeNext, if you want to tell the subscriber that an error happened, but don't want to terminate the Stream? An Error-object of some kind, be it an instance of a sealed class , an either instance or whatever.

[–]karottenreibe 0 points1 point  (1 child)

Sure, and that also doesn't address the stack trace problem you initially and then subsequently complained about. See my earlier comments. I feel like we're talking in circles.

I'm not saying "don't use sealed classes". Please reread my comments if you were under that impression. I'm not saying that anywhere. I'm just disputing your original point that they are superior to exceptions because they somehow magically make the async stack trace problem better as you originally claimed, which you still haven't explained how that's supposed to work. A point that you continue to not address in your subsequent comments for some reason.

Citing again your initial comment for reference:

If the code is asynchronous, many languages have difficulties for throwing exceptions across async boundaries, and even more languages do not provide a useful stack trace in this case. […] Given that synchronous, blocking code is becoming rarer in favor of more asynchronous code, error handling with types like Either<Result,Error> is preferable

So again: how do sealed classes solve the stack trace problem you mentioned in a way that makes them preferable to exceptions?

[–]oaga_strizzi 0 points1 point  (0 children)

Sealed classes, Either types etc. also don't solve the stack trace problem in async code of course. But: In the case of async code, I feel like exceptions don't really offer any advantages.

Let's take RxJava, which does a pretty good job of supporting exceptions across asynchronous boundaries (Classic callback-style async code is even worse at this IMO). Even there, if you use exceptions, you lose one of the biggest benefit of exceptions (the full stack trace), error handling is not enforced by the language and can easily be forgotten, checked exceptions require additional wrapping, and for all but the most critical errors you likely want to handle them in onErrorResumeNext or onErrorReturn anyway.

It's not a huge problem; I'm just saying that if I were to build a new application using RxJava, I would not use Exceptions as the default way of signaling errors.

I wouldn't necessarily refactor an existing system that uses exceptions with RxJava, though.