Skip to content

Commit

Permalink
insert a synthetic stack trace element for rx2 errors
Browse files Browse the repository at this point in the history
This should make identifying errors reported in firebase easier, since it should help ensure
that class names are deobfuscated (compared to the previous apprach)
  • Loading branch information
pettermahlen committed Apr 21, 2020
1 parent 9b78f1e commit c27af06
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 4 deletions.
1 change: 1 addition & 0 deletions mobius-rx2/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dependencies {
testImplementation "org.hamcrest:hamcrest-library:${versions.hamcrestLibrary}"
testImplementation "ch.qos.logback:logback-classic:${versions.logback}"
testImplementation "org.awaitility:awaitility:${versions.awaitility}"
testImplementation "org.assertj:assertj-core:${versions.assertjcore}"
testImplementation "com.google.auto.value:auto-value-annotations:${versions.autoValue}"
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* -\-\-
* Mobius
* --
* Copyright (c) 2017-2018 Spotify AB
* --
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* -/-/-
*/
package com.spotify.mobius.rx2;

import com.spotify.mobius.ConnectionException;

/**
* Helper exception type that enables capturing the correct class and method for exceptions
* happening in {@link io.reactivex.ObservableTransformer}s.
*/
class EffectHandlerException extends ConnectionException {

private EffectHandlerException(Throwable throwable) {
super("Error in effect handler", throwable);
}

public static EffectHandlerException in(Object effectHandler, Throwable cause) {
EffectHandlerException e = new EffectHandlerException(cause);

final StackTraceElement[] stackTrace = e.getStackTrace();

// add a synthetic StackTraceElement so that the effect handler class name will be reported in
// the exception. This helps troubleshooting where the issue originated from.
stackTrace[0] = new StackTraceElement(effectHandler.getClass().getName(), "apply", null, -1);

e.setStackTrace(stackTrace);

return e;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

import static com.spotify.mobius.internal_util.Preconditions.checkNotNull;

import com.spotify.mobius.ConnectionException;
import com.spotify.mobius.Mobius;
import com.spotify.mobius.MobiusLoop;
import com.spotify.mobius.Update;
Expand Down Expand Up @@ -481,9 +480,7 @@ public ObservableTransformer<F, E> build() {
private static <F, E> Consumer<Throwable> defaultOnError(
final ObservableTransformer<? extends F, E> effectHandler) {
return throwable ->
RxJavaPlugins.onError(
new ConnectionException(
"in effect handler: " + effectHandler.getClass().toString(), throwable));
RxJavaPlugins.onError(EffectHandlerException.in(effectHandler, throwable));
}

private interface OnErrorFunction<T, R> extends Function<T, R> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* -\-\-
* Mobius
* --
* Copyright (c) 2017-2018 Spotify AB
* --
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* -/-/-
*/
package com.spotify.mobius.rx2;

import static org.assertj.core.api.Assertions.assertThatThrownBy;

import org.junit.Test;

public class EffectHandlerExceptionTest {

private static class PretendEffectHandler {}

@Test
public void shouldProvideAGoodStackTrace() throws Exception {
final RuntimeException cause = new RuntimeException("hey");

assertThatThrownBy(
() -> {
throw EffectHandlerException.in(new PretendEffectHandler(), cause);
})
.hasStackTraceContaining(PretendEffectHandler.class.getName())
.hasCause(cause);
}
}

0 comments on commit c27af06

Please sign in to comment.