-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1401 from samhendley/onnextvalue
OnError while emitting onNext value: object.toString
- Loading branch information
Showing
2 changed files
with
127 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
rxjava-core/src/test/java/rx/exceptions/OnNextValueTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package rx.exceptions; | ||
|
||
import org.junit.Test; | ||
import rx.Observable; | ||
import rx.Observer; | ||
import rx.functions.Func1; | ||
|
||
import java.io.PrintWriter; | ||
import java.io.StringWriter; | ||
|
||
import static org.junit.Assert.assertTrue; | ||
import static org.junit.Assert.fail; | ||
|
||
/** | ||
* ```java | ||
* public OnNextValue(Object value) { | ||
* super("OnError while emitting onNext value: " + value); | ||
* this.value = value; | ||
* } | ||
* ``` | ||
* I know this is probably a helpful error message in some cases but this can be a really costly operation when an objects toString is an expensive call or contains alot of output. I don't think we should be printing this in any case but if so it should be on demand (overload of getMessage()) rather than eagerly. | ||
* <p/> | ||
* In my case it is causing a toString of a large context object that is normally only used for debugging purposes which makes the exception logs hard to use and they are rolling over the log files very quickly. | ||
* <p/> | ||
* There is an added danger that if there is a bug in the toString method it will cause inconsistent exception creation. If the object throws an exception while rendering a string it will actually end up not seeing the real exception. | ||
*/ | ||
public final class OnNextValueTest { | ||
private static class BadToString { | ||
|
||
private final boolean throwDuringToString; | ||
|
||
private BadToString(boolean throwDuringToString) { | ||
this.throwDuringToString = throwDuringToString; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
if (throwDuringToString) { | ||
throw new IllegalArgumentException("Error Making toString"); | ||
} else { | ||
return "BadToString"; | ||
} | ||
} | ||
} | ||
|
||
private static class BadToStringObserver implements Observer<BadToString> { | ||
@Override | ||
public void onCompleted() { | ||
System.out.println("On Complete"); | ||
fail("OnComplete shouldn't be reached"); | ||
} | ||
|
||
@Override | ||
public void onError(Throwable e) { | ||
String trace = stackTraceAsString(e); | ||
System.out.println("On Error: " + trace); | ||
|
||
assertTrue(trace, trace.contains("OnNextValue")); | ||
|
||
assertTrue("No Cause on throwable" + e, e.getCause() != null); | ||
assertTrue(e.getCause().getClass().getSimpleName() + " no OnNextValue", | ||
e.getCause() instanceof OnErrorThrowable.OnNextValue); | ||
} | ||
|
||
@Override | ||
public void onNext(BadToString badToString) { | ||
System.out.println("On Next"); | ||
fail("OnNext shouldn't be reached"); | ||
|
||
} | ||
} | ||
|
||
public static String stackTraceAsString(Throwable e) { | ||
StringWriter sw = new StringWriter(); | ||
e.printStackTrace(new PrintWriter(sw)); | ||
return sw.toString(); | ||
} | ||
|
||
@Test | ||
public void addOnNextValueExceptionAdded() throws Exception { | ||
Observer<BadToString> observer = new BadToStringObserver(); | ||
|
||
Observable.from(new BadToString(false)) | ||
.map(new Func1<BadToString, BadToString>() { | ||
@Override | ||
public BadToString call(BadToString badToString) { | ||
throw new IllegalArgumentException("Failure while handling"); | ||
} | ||
}).subscribe(observer); | ||
|
||
} | ||
|
||
@Test | ||
public void addOnNextValueExceptionNotAddedWithBadString() throws Exception { | ||
Observer<BadToString> observer = new BadToStringObserver(); | ||
|
||
Observable.from(new BadToString(true)) | ||
.map(new Func1<BadToString, BadToString>() { | ||
@Override | ||
public BadToString call(BadToString badToString) { | ||
throw new IllegalArgumentException("Failure while handling"); | ||
} | ||
}).subscribe(observer); | ||
|
||
} | ||
} |