-
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
2.x: CreateEmitter throws when onError called after dispose unlike 1.x #4880
Comments
Working solution is to manually check if the emitter is not disposed before calling |
In 2.x, we signal all undeliverable exceptions, such as yours to the |
But as a library would I want to set an onError handler in the RxJavaPlugins? |
It depends. You can read the current handler and chain with it, but otherwise you should try to avoid calling onError if the downstream is not ready. Why does an uncaught exception crash an app btw? |
Alternative is that we modify the default behavior and don't call the default uncaught exception handler. There could be a system parameter that disables or enables this behavior (depending on what the default should be). |
Yeah, I've now added a check for I was mostly confused why the behaviour between 1.x and 2.x differs for Emitters, but your |
I'll close this for now. I think the new behaviour is okay and makes sense. Maybe a small note in the docs of Emitter would help to just clear up that |
Also hit this error unexpectedly. A note or something would be helpful. I'm of the opinion that if the emitter is disposed errors should be ignored. At most logged. Maybe my interpretation of disposed is wrong. To me I'm essentially saying "I don't care about the result any more" when I call dispose. Bubbling it up as an uncaught exception after it's disposed is treating it like it's an important issue. In an Android application this means a crash dialog for something that happened in the background from something that was cancelled. |
The problem is that you then sweep actual programming errors under the rug
and don't crash when there's an actual problem.
…On Mon, Jan 23, 2017, 10:47 PM Daniel Brain ***@***.***> wrote:
Also hit this error unexpectedly. A note or something would be helpful.
I'm of the opinion that if the emitter is disposed errors should be
ignored. At most logged. Maybe my interpretation of disposed is wrong. To
me I'm essentially saying "I don't care about the result any more" when I
call dispose. Bubbling it up as an uncaught exception after it's disposed
is treating it like it's an important issue.
In an Android application this means a crash dialog for something that
happened in the background from something that was cancelled.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#4880 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAEEEYm9L24dx849xQORO_pkRDlOgi7oks5rVXRVgaJpZM4K6-q8>
.
|
I wrote a small Android library to get location data from Google Play Services via rx's Observables and I've recently stumbled on this issue as well. It happens, albeit rarely, at this line: https://github.com/julioromano/RxLocation/blob/v0.11.0-beta/rxlocation/src/main/java/net/kjulio/rxlocation/LastLocationHelper.java#L34 What I'm trying to do about it is to guard all calls to Apart from debugging purposes I don't see any scenario where one would want a call to I bet my knowledge on the topic is limited so can somebody explain when such a scenario would be desirable (except for the debugging case) ? |
See the wiki about 2.x and error handling. |
Some blocking APIs throw an See the wiki for further details. |
I get the idea of not sweeping errors under the rug but I ran into a race condition because of this. The code was working perfectly in testing but we got productive crashes. I investigated and found this to throw an exception:
It happens when the emitter is disposed between the if (! emitter.isDisposed()) and the emitter.onError and the emitter is disposed because there is a timeout on the rx flow that creates the emitter. As a workaround I put a wrapper around the emitter that catches our custom exceptions in onError but it would be convenient to have an official way to ignore exceptions in the onError. |
I've been considering a pair of new methods: |
Hmm, just seeing this issue myself now. I understand the point of view that not emitting the error would be "sweeping it under the rug", but how do we deal with the error if we no longer have a handler? I'm essentially now "sweeping it under the rug" in the new global handler. For example, I have an instance that downloads certain assets while the user is logged in. If this is happening while the user logs out the Disposable listening to this download is disposed. And then the download fails and throws because the user is no longer logged in. So here we have a guaranteed error thrown that we definitely do not care about (user no longer logged in) so we "sweep it under the rug" anyway. |
See FlowableEmitter.tryOnError and similar methods since 2.1.1 . |
This new behavior is a little overboard IMHO, but what do I know... In order to get around this I created a wrapper class for the data type I'm actually trying to emit. The wrapper class also has a Throwable field and an int field to identify the emit/event type (Success or Error). Then, I just use the onNext() function (instead of onError()) with the emitted wrapper object initialized with a Throwable and appropriate int field to let the handler know it's looking at a non-critical error. The onError() function can then be reserved for critical errors where everything must be brought down or released, etc... |
I see this issue in 2.2.6.
Upstream, at remote end point quite simple:
Only solution for me was to add RxJavaPlugins.setErrorHandler() as it described at wiki and ignore MyException. Say me if you need more info or any. |
If there are more operators that can have error/cancel races, you'd still likely have an undeliverable exception. The only reliable solution is to set the plugin error handler and decide if the original exception needs to be handled or not. |
I have these two tests which behave differently in 1.x and 2.x.
The 2.x
CreateEmitter
ends up throwing the exception as an uncaught exception, the 1.x Emitter just returns if the Subscription has already been unsubscribed.The Wiki at Entering the Reactive World makes it sounds like both should behave the same.
What would be the correct usage in 2.x to get the same behaviour as in 1.x and not crashing the Application with the
emitter.onError(...)
call?The text was updated successfully, but these errors were encountered: