-
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
1.x: add Completable.safeSubscribe option + RxJavaPlugins hook support #3942
Conversation
In my opinion safe wrapping should be the default as it's the default in |
|
||
/** | ||
* Subscribes the given CompletableSubscriber to this Completable instance | ||
* and handles exceptions throw by its onXXX methods. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throw -> thrown
Should the tests about error handling plugin in #3938 be here? Or we leave it in that PR? |
@bryant1410 Your PR has a test failure:
|
Fixed typo, renamed methods |
@akarnokd They fail on purpose because I made the test but didn't fix the problem (Completable is not calling the error handling plugin). |
@@ -1992,7 +2014,7 @@ public final void subscribe(CompletableSubscriber s) { | |||
throw new NullPointerException("The RxJavaPlugins.onSubscribe returned a null Subscriber"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can only happen if s
is null
, which is checked in requiredNonNull(s)
. Same in subscribe(Subscriber)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, why using sw
? Is just an alias of s
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's there to capture plugin errors once the plugin API is extended.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean once there is an execution hook for Completable
? Or what do you mean?
The methods should be the other way around. Following |
The |
Updated with plugin support. |
Can you cherry-pick the commit that adds tests for the error handling plugn in |
Sure. |
unconditionally.
Done. |
@@ -52,8 +52,8 @@ public void onCompleted() { | |||
|
|||
@Override | |||
public void onError(Throwable e) { | |||
RxJavaPluginUtils.handleException(e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be done if !done
, as in SafeSubscriber
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done or not, the exception has to be reported to the handler. This also makes your test pass.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But why SafeSubscriber
doesn't do this? Either this class or the other one are not behaving right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you demonstrate that with an unit test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want me to make a unit test for the case that onError
gets called twice in a SafeSubcriber
and SafeCompletableSubscriber
to see if the error handler gets called twice? I don't know if it's worth it. What it happens is that it just doesn't look good to me when behavior is different in Completable
from Single
and Observable
.
The comment |
@@ -1843,7 +1846,7 @@ public final Completable startWith(Completable other) { | |||
*/ | |||
public final Subscription subscribe() { | |||
final MultipleAssignmentSubscription mad = new MultipleAssignmentSubscription(); | |||
subscribe(new CompletableSubscriber() { | |||
unsafeSubscribe(new CompletableSubscriber() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SafeCompletableSubscriber
is not used here nor the others subscribe
methods, except for subscribe(Subscriber)
. I think subscribe
methods should call between themselves (as in Observable#subscribe
methods) to refactor code and avoid forgetting this kind of things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unsafeSubscribe
should call between themselves too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should call subscribe
now instead, doesn't it? And the others subscribe
methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the rest are intermediate operators or already perform custom logic in addition to reporting the error to a plugin. Plus, this particulare use case, the subscriber is not expected to crash.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But the idea of the safe subscribe is to ensure the caller that the contract will be met. Why in this particular case it won't?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But SafeSubscriber
in the first line of the javadocs says:
SafeSubscriber is a wrapper around Subscriber that ensures that the Subscriber complies with the Observable contract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. However, this method doesn't run any user supplied code and thus no need to wrap it into a safe completable subscriber.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. However, the other 2 subscribe
methods that don't use SafeCompletableSubscriber
should do it. To assert that the Action
instances are called at most once, and not both, complying with the contract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the safeguard to those methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Why not reusing SafeCompletableSubscriber
?
Removed comment, changed to reuse methods, added onStart call. |
* | ||
* @return {@link RxJavaCompletableExecutionHook} implementation to use | ||
*/ | ||
public RxJavaCompletableExecutionHook getCompletableExecutionHook() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Experimental
Please add the missing |
Added missing annotations |
* returned as a pass through | ||
*/ | ||
public <T> Completable.CompletableOnSubscribe onCreate(Completable.CompletableOnSubscribe f) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
👍 |
Add option to safely subscribe a
CompletableSubscriber
/ regularSubscriber
and handleonXXX
failures.See also: #3938
Naming and whether or not the safe wrapping should be the default is open to discussion.