-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Observer#onError should use Throwable #296
Comments
Throwable only has 2 sub-classes
Thus, all application Exceptions capable of being handled should extend from What are the use cases in which we should be catching and passing Also of note, this is a breaking change (not a deal breaker since we are pre-1.0, but it's a factor). |
theoretically speaking, you are right. one practical use case would be when I want to allow observer there are cases when it is OK for large block heap allocations to fail |
I have handled that use case before (years ago when working on search engines where it made sense to catch OOME). However, I'd suggest that is an edge case that should be caught by the specific code and turned into an Developers should not be expected to handle an Here is an example of what I'd suggest to comply with the principle of not throwing return Observable.create(new Func1<Observer<String>, Subscription>() {
def Subscription call(Observer<String> observer) {
try {
// allocate memory
observer.onNext("some value");
observer.onCompleted();
} catch(OutOfMemoryError e) {
observer.onError(new RuntimeException("Recoverable OutOfMemory on optional ... "));
}
return Subscriptions.empty();
};
}); |
I agree with the general sentiment that One problem we ran into, however, was that throwing |
My 2p on the issue. If there's a chance of "user code" being in the stack leading to Other reasons to prefer Throwable is that the cause of any exception is a throwable. Apis that try to coerce to exception often wrap throwables (sometimes incorrectly) just to handle exception.getCause. This implies that those using or maintaining the system need to carefully review all try-catch blocks before they know that onError will in fact be called and not just propagate stuff and leave them hanging. While there are still cases onError won't be called, due to JVM crash, etc, I think it is still an advantage. It is possible that Observer writers could be turned off due to throwable. This could be good or bad.. I see this as "hey.. you really should pay attention!!". Those who insist they don't like to receive throwable can punt using or making utilities such as [propagate](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Throwables.html#propagateIfInstanceOf(java.lang.Throwable, java.lang.Class). Summary is that if we allow onError to receive a throwable, we are being more honest to the observer about their failures. It will be called more often (for example, it can accept an Error) or would be called with less wrapped things. The try blocks maintaining the stack until onError are simpler and can directly correspond to exception.getCause. The benefits of |
One thing to clarify here is that whether or not to send a throwable signal to the observer is a different issue than whether the code managing the observer propagates errors. If we decide to notify observers when an error (or any other throwable) caused their request to cease, this doesn't imply we are swallowing errors in the RXjava code that calls |
I'm strongly against catching |
@jmhofer onError() is basically a message. It doesn't imply the receiver should propagate it. It only informs them what happened, right? Choosing to restrict onError from accepting throwable is a choice to not know why or if your observer was cancelled. I can't side with that. |
wrt "Also, calling onError for an Error and at the same time rethrowing it would be confusing, imho." It isn't confusing if we understand |
I agree that raising the error after signaling is better than swallowing it. - Still wouldn't want to handle what basically comes down to a developer's error in |
@jmhofer do you mean stick to traditional single-method observer and don't have an onError callback? (hence no discussion about it) |
@adriancole No, I just think that |
there's several examples of where Throwable is validly sent to callers [1] } catch (Throwable t) { |
If we wished to keep the interface, and avoid the "error made me hang |
Possibly dead horse, at this point, but every current java async web callback chose throwable, not exception, for error signals. If we chose to retain Exception as opposed to Throwable, converting to or from these interfaces will be lossy. |
Those are some very strong arguments and I'm mostly convinced that it's worth changing to To adopt I don't like however that Perhaps we should create a new What other implications are there if we proceed with this change? |
Anyone have further thoughts on this issue, particularly the use cases I explained in my last comment regarding |
sounds like a good idea: using only one: onExceptionResumeNext |
@Andrei-Pozolotin @adriancole @jmhofer @mttkay @michaeldejong @mairbek I have submitted a pull request #315 with the breaking change of I would like to merge and release within 24 hours if possible. |
Change onError(Exception) to onError(Throwable) - Issue #296
See issue "Observer#onError should use Throwable" for background => ReactiveX#296
See ReactiveX#296 (comment) for context.
…wable Change onError(Exception) to onError(Throwable) - Issue ReactiveX#296
See issue "Observer#onError should use Throwable" for background => ReactiveX#296
See ReactiveX#296 (comment) for context.
* Add AsyncRateLimiterMetrics * Cleanup imports and docstring * Rename ofRateLimiter to ofAsyncRetry * Add tests around AsyncRetry * Remove async method from HelloWorldService * Formatting * Individual imports * rearrange imports * Add license headers and test * cleanup headers??? * Test failed futures instead of throw * Remove throws statements * Update documentation
current signature
https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/main/java/rx/Observer.java#L45
uses Exception; instead, lets use Throwable
The text was updated successfully, but these errors were encountered: