Skip to content
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

Unhandled errors go to UncaughtExceptionHandler #1766

Merged
merged 1 commit into from
Oct 16, 2014

Conversation

loganj
Copy link
Contributor

@loganj loganj commented Oct 16, 2014

Rather than swallowing/logging errors, ScheduledAction now delivers them
to the UncaughtExceptionHandler for the executing Thread. This gives
client applications control over the handling of errors that occur off
of the calling Thread.

Rather than swallowing/logging errors, ScheduledAction now delivers them
to the UncaughtExceptionHandler for the executing Thread. This gives
client applications control over the handling of errors that occur off
of the calling Thread.
@benjchristensen
Copy link
Member

Thank you @loganj

@loganj
Copy link
Contributor Author

loganj commented Oct 16, 2014

Oops, forgot to reference the original issue: #1682

benjchristensen added a commit that referenced this pull request Oct 16, 2014
Unhandled errors go to UncaughtExceptionHandler
@benjchristensen benjchristensen merged commit 78b7b59 into ReactiveX:1.x Oct 16, 2014
@benjchristensen
Copy link
Member

I haven't had a chance to test yet, but without printStackTrace will this silently fail unless someone has registered a default handler, or does the JVM have a default one?

@loganj
Copy link
Contributor Author

loganj commented Oct 16, 2014

Pretty sure ThreadGroup has us covered.

If this thread group has a parent thread group, the uncaughtException method of that parent is called with the same two arguments.

Otherwise, this method checks to see if there is a default uncaught exception handler installed, and if so, its uncaughtException method is called with the same two arguments.

Otherwise, this method determines if the Throwable argument is an instance of ThreadDeath. If so, nothing special is done. Otherwise, a message containing the thread's name, as returned from the thread's getName method, and a stack backtrace, using the Throwable's printStackTrace method, is printed to the standard error stream.

@benjchristensen
Copy link
Member

Ah nice. That's exactly what I'd want it to do. I'll play to confirm.

Thanks @loganj for helping out with this.

@benjchristensen
Copy link
Member

Confirmed. It works perfectly.

    public static void main(String[] args) throws Exception {

        Observable.interval(100, TimeUnit.MILLISECONDS).map(i -> {
            throw new RuntimeException("fail!");
        }).subscribe();

        Thread.sleep(100000);
    }

outputs to terminal

Exception in thread "RxComputationThreadPool-1" java.lang.IllegalStateException: Exception thrown on Scheduler.Worker thread. Add `onError` handling.
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:50)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: rx.exceptions.OnErrorNotImplementedException: fail!
    at rx.Observable$36.onError(Observable.java:7390)
    at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:127)
    at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:96)
    at rx.internal.operators.OperatorMap$1.onError(OperatorMap.java:48)
    at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:56)
    at rx.internal.operators.OnSubscribeTimerPeriodically$1.call(OnSubscribeTimerPeriodically.java:51)
    at rx.Scheduler$Worker$1.call(Scheduler.java:118)
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:45)
    ... 7 more
Caused by: java.lang.RuntimeException: fail!
    at ErrorsTest.lambda$0(ErrorsTest.java:10)
    at ErrorsTest$$Lambda$1/1406718218.call(Unknown Source)
    at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:54)
    ... 10 more
Caused by: rx.exceptions.OnErrorThrowable$OnNextValue: OnError while emitting onNext value: Long.class
    at rx.exceptions.OnErrorThrowable.addValueAsLastCause(OnErrorThrowable.java:98)
    at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:56)
    ... 10 more

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants