Skip to content

Commit

Permalink
Strawman proposal for uncaught exception configuration
Browse files Browse the repository at this point in the history
This is a strawman example/proposal for configurable uncaught exception handling in RxJavaPlugins. This is in ref to ReactiveX#5234.

The two options are to defer to current thread's handler (the current implementation and remains the default) and an optional `throw` option that wraps the throwable into an `UncaughtRxJavaException` for developers to watch for separately (and rethrowing, which requires some sort of `RuntimeException` wrapping).
  • Loading branch information
ZacSweers committed Aug 26, 2017
1 parent 994c65d commit 54ac1dd
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
34 changes: 31 additions & 3 deletions src/main/java/io/reactivex/plugins/RxJavaPlugins.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,27 @@
import io.reactivex.schedulers.Schedulers;
/**
* Utility class to inject handlers to certain standard RxJava operations.
* <p>
* <strong>Supported system properties ({@code System.getProperty()}):</strong>
* <ul>
* <li>{@code rx2.uncaught-behavior} (String): sets the behavior of the uncaught exception handling, default is {@link #UNCAUGHT_HANDLER}. This is {@link Experimental}.</li>
* </ul>
*/
public final class RxJavaPlugins {

/**
* System property value for uncaught exceptions that passes the exception directly to the current thread's
* {@link UncaughtExceptionHandler}. This is the default behavior.
*/
@Experimental
public static final String UNCAUGHT_HANDLER = "handler";

/**
* System property value for uncaught exceptions that just immediately throws the uncaught exception.
*/
@Experimental
public static final String UNCAUGHT_THROW = "throw";

@Nullable
static volatile Consumer<? super Throwable> errorHandler;

Expand Down Expand Up @@ -123,6 +142,9 @@ public final class RxJavaPlugins {
*/
static volatile boolean failNonBlockingScheduler;

/** The name of the system property for setting the uncaught exception behavior. */
private static final String KEY_UNCAUGHT_BEHAVIOR = "rx2.uncaught-behavior";

/**
* Prevents changing the plugins from then on.
* <p>This allows container-like environments to prevent clients
Expand Down Expand Up @@ -406,9 +428,15 @@ static boolean isBug(Throwable error) {
}

static void uncaught(@NonNull Throwable error) {
Thread currentThread = Thread.currentThread();
UncaughtExceptionHandler handler = currentThread.getUncaughtExceptionHandler();
handler.uncaughtException(currentThread, error);
String uncaughtBehavior = System.getProperty(KEY_UNCAUGHT_BEHAVIOR, UNCAUGHT_HANDLER);
if (UNCAUGHT_THROW.equals(uncaughtBehavior)) {
throw new UncaughtRxJavaException(error);
} else {
Thread currentThread = Thread.currentThread();
UncaughtExceptionHandler handler = currentThread.getUncaughtExceptionHandler();
handler.uncaughtException(currentThread, error);
}
// TODO Error on invalid inputs somehow?
}

/**
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/io/reactivex/plugins/UncaughtRxJavaException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.reactivex.plugins;

import io.reactivex.annotations.Experimental;

/**
* An exception thrown when an uncaught throwable was received and the {@link RxJavaPlugins#UNCAUGHT_THROW} property was
* set. This guarantees the existence of an underlying cause retrievable via {@link #getCause()}.
*/
@Experimental
public final class UncaughtRxJavaException extends RuntimeException {

public UncaughtRxJavaException(Throwable cause) {
super(cause);
}

}

0 comments on commit 54ac1dd

Please sign in to comment.