-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Stack trace is opaque for IllegalStateException: Exception thrown on Scheduler.Worker thread. Add onError
handling.
#2293
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
Comments
You can simply add an |
Right, but given I have hundreds of places that I could add that onError handler to, and decoupled stacktrace, I have no obvious place to start. |
You can register a global error handler if you don't have specific error handlers. We use it at Netflix to track unhandled errors. Take a look at http://reactivex.io/RxJava/javadoc/rx/plugins/RxJavaPlugins.html#registerErrorHandler(rx.plugins.RxJavaErrorHandler) |
Since you haven't defined an error handler all that can be done is register the uncaught exception. This has been discussed at length, particularly in #1682 and #1766 which added the Errors are propagated down, not up, when going across thread boundaries. When an exception is thrown up, as happens when there is no error handler defined, it will eventually hit the thread boundary and then we send it to the ErrorPlugin and register it with the So you have 3 options:
Now a few more specific questions:
This jumped out at me as that number doesn't sound right. If you have hundreds of places where you are subscribing that generally indicates a problem (unless your application is rather large or has many distinct use cases). The
What particular questions do you have about causes? The operators involved are generally going to be
The stack trace you showed suggests it is probably a
This is the biggest weakness of async code because JVM callstacks are intended for synchronous imperative code. I personally am researching solutions for stitching together artificial callstacks that show the actual user code instead of the JVM callstacks which show the Rx library, but to do it without killing performance requires digging into the native JVM code via native java agents. Thus it will not be an option for Android. We may be able to create one for debugging purposes that uses normal Java, but it would be far too slow to ever enable in production (as it involves capturing a stacktrace at every operator invocation). Another route we are exploring is the use of the plugins for debugging and capturing the callgraph as a stream of events. We have succeeded in getting the graph of events, but not yet had time to create a UI to make it usable. You can see the effort so far at https://github.com/ReactiveX/RxJavaDebug Again, this would be too slow for production use except for cases where it is dynamically enabled just for tracing a particular request. What suggestions do you have and what would you like to help improve? |
@benjchristensen thank you for taking the time to answer. I think I understand the difficulty here. I've already got an
You're right. Performing a search for
I see where the stack trace references timer, but I don't see any obvious references to combineLatest without knowing more about the internals of the library. I don't use timer directly in my client code, but I do use For the time being, is there some way I can apply a global backpressure strategy, knowing that it will have negative side-effects, until I can properly address my problems? |
You can apply onBackpressureBuffer to your source and it will make it behave the same as before. If that isn't an option you can set a global property for rx.ring-buffer.size to a value higher than your max stream length. |
Another curiosity for me to better understand how things get used. Why do you end up using Workers/SchedulePeriodically directly instead of an operator like interval?= |
In my opinion, it happens because programmers come from the classical Executor training and find the Scheduler as the nearest thing to work with periodically. The second cause, I think, is that not using a value from a source and mapping in something else is a strange way of doing async work. (I.e., using Maybe the detailing of the scheduler API should be an advanced topic described way after the use of operators such as timer and interval. Besides, using the Worker correctly to avoid leaks in operators or in user code is IMO an advanced topic. |
@benjchristensen Naivety. Like I said, I've begun re-writing the app to eliminate some of these novice mistakes. Something like edit) @akarnokd is fairly spot on. The API feels familiar and is accessible. Can you elaborate on:
|
That's a good enough reason :-) It took me many months before I was using this style of programming correctly. What would you suggest we improve to provide education and examples for how to do things idiomatically and functionally? I was lucky to have an expert close by when I was learning so I could ask lots of questions. Without that it would have been far harder. As you have learned, what do you wish you could have been provided by the RxJava project early on to teach you? |
@benjchristensen I'm under a fairly tight deadline right now, but I'll try to review the current education resources and get you some feedback soon. I picked up RxJava-Android (when it was called that) back in March 2014; my interest was originally piqued having used ReactiveCocoa on iOS. Much of what I've picked up has been from a combination of the documents from https://github.com/ReactiveX/RxJava/wiki/The-RxJava-Android-Module and hard-won from ReactiveCocoa's Github issues. Luckily most of the Rx contract is upheld between the two implementations ;) |
@benjchristensen Not sure if my suggestion is solid. I have seen the following above:
The problem I am facing right now is that somewhere there is not placed an onError so it causes the (android) program to crash. It would be very helpful to see the codeline of the original Action0 (or something similar) so we can easily locate the problem. Of course I do not know the implications of the whole JVM - as you say above. Update for further people hitting this from google:
|
We are actively exploring this space, but nothing usable yet. Also, it is only for the Hotspot/OpenJDK/Oracle JVMs that we are pursuing anything right now. I don't know what the options are for Android. Just the other day I saw some native C code via native plugins and also via JNI allowing a logical callstack across async boundaries. Performance is still an issue though. Beyond that I don't have much further to offer as a solution at this time. We still use println logging (via |
I am toying with RxJava and I had this issue as well. I think ReactiveX should be very careful to explain the difference between Observable.doOnError (side effect, will still blow up) and Subscriber.onError (last consumer, if handled here your error won't pop anymore. At least that was my problem. https://twitter.com/Corlaez/status/782023068793339904 |
maybe callback run in wrong thread. |
it occurs to me that Action1<> can be dangerous to use, given that Observable.subscribe will throw unchecked exception in onError ... ex:
this code generates MissingBackpressureException, which propogates to OnErrorNotImplementedException then is wrapped in IllegalStateException ... but in ScheduledAction.run, calls |
That seems normal. If you don't supply what is the reactive equivalent of a
catch block then the exception propagates resulting in app death. Supply an
error handler and the problem goes away.
…On Sun, Nov 27, 2016, 10:53 PM GuBo ***@***.***> wrote:
it occurs to me that Action1<> can be dangerous to use, given that
Observable.subscribe will throw unchecked exception in onError ... ex:
` final rx.plugins.RxJavaErrorHandler rxJavaErrorHandler = new
rx.plugins.RxJavaErrorHandler() {
@OverRide <https://github.com/Override>
public void handleError( final Throwable x ) {
System.out.println( "rxJavaErrorHandler.handleError: " +
x.getClass().getSimpleName() );
}
};
rx.plugins.RxJavaPlugins.getInstance().registerErrorHandler(
rxJavaErrorHandler );
final rx.functions.Action1<Long> action = new rx.functions.Action1<Long>() {
@OverRide
public void call( final Long L ) {
System.out.println( "tick" );
try { Thread.sleep( 2500 ); } catch ( InterruptedException x ) {}
}
};
final rx.Subscription subscription = rx.Observable.interval( 100L,TimeUnit.MILLISECONDS )
.subscribeOn( rx.schedulers.Schedulers.io() )
.observeOn( rx.schedulers.Schedulers.newThread() )
.subscribe( action );`
this code generates MissingBackpressureException, which propogates to
OnErrorNotImplementedException then is wrapped in IllegalStateException ...
but in ScheduledAction.run, calls
RxJavaPlugins.getInstance().getErrorHandler().handleError(ie); and then
regardless calls thread.getUncaughtExceptionHandler().uncaughtException(thread,
ie);
to me this means you don't really get to "handle" the error in your
registered RxJavaPlugins error handler.
on android, this will kill the process.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#2293 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAEEEYQnNW4Hqy1bK6ssdmWzvsUYCyr5ks5rClBLgaJpZM4DNEGU>
.
|
but rx.plugins.RxJavaPlugins.getInstance().registerErrorHandler( rxJavaErrorHandler ); if i put .doOnError( Action1... ) after .observeOn, it gets called but the chain (if i subscribe on a SafeSubscriber, i.e. new rx.Observer<>... then there is not the problem ... problem is with subscribing with an Action1) |
The problem is this:
You have to handle exception by consuming it via .subscribe( action, error -> errorHandler(error) ); |
I am trying a program in android studio which was provided by ResearchStack. I am acing the same error and I now I should use an Error Handler to solve this issue. But the RxJava program is an executable jar file of RxJava. So where can I add the error handler program? |
This occurs when using RxAndroid 0.23.0/RxJava 1.0.0, please redirect me if this is not the most appropriate place for this.
There seem to be a several ways to cause the following exception, notably using observeOn() on a when there exists overproducing or underconsuming, and there is no clear association with client code:
I'd like to strike up a discussion highlighting common causes on these backpressure exceptions, how to determine the source of them in client code, and finally how to improve the stacktrace.
The text was updated successfully, but these errors were encountered: