/** * Copyright 2014 Netflix, Inc. * * 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 rx.plugins; import rx.Observable; import rx.Subscriber; import rx.annotations.Experimental; import rx.exceptions.Exceptions; import rx.exceptions.OnErrorThrowable; /** * Abstract class for defining error handling logic in addition to the normal * {@link Subscriber#onError(Throwable)} behavior. * <p> * For example, all {@code Exception}s can be logged using this handler even if * {@link Subscriber#onError(Throwable)} is ignored or not provided when an {@link Observable} is subscribed to. * <p> * This plugin is also responsible for augmenting rendering of {@code OnErrorThrowable.OnNextValue}. * <p> * See {@link RxJavaPlugins} or the RxJava GitHub Wiki for information on configuring plugins: <a * href="https://github.com/ReactiveX/RxJava/wiki/Plugins">https://github.com/ReactiveX/RxJava/wiki/Plugins</a>. */ public abstract class RxJavaErrorHandler { /** * Receives all {@code Exception}s from an {@link Observable} passed to * {@link Subscriber#onError(Throwable)}. * <p> * This should <em>never</em> throw an {@code Exception}. Make sure to try/catch({@code Throwable}) all code * inside this method implementation. * * @param e * the {@code Exception} */ public void handleError(Throwable e) { // do nothing by default } protected static final String ERROR_IN_RENDERING_SUFFIX = ".errorRendering"; /** * Receives items causing {@code OnErrorThrowable.OnNextValue} and gives a chance to choose the String * representation of the item in the {@code OnNextValue} stacktrace rendering. Returns {@code null} if this * type of item is not managed and should use default rendering. * <p> * Note that primitive types are always rendered as their {@code toString()} value. * <p> * If a {@code Throwable} is caught when rendering, this will fallback to the item's classname suffixed by * {@value #ERROR_IN_RENDERING_SUFFIX}. * * @param item the last emitted item, that caused the exception wrapped in * {@code OnErrorThrowable.OnNextValue} * @return a short {@link String} representation of the item if one is known for its type, or null for * default * @since (if this graduates from Experimental/Beta to supported, replace this parenthetical with the * release number) */ @Experimental public final String handleOnNextValueRendering(Object item) { try { return render(item); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } catch (Throwable t) { Exceptions.throwIfFatal(t); } return item.getClass().getName() + ERROR_IN_RENDERING_SUFFIX; } /** * Override this method to provide rendering for specific types other than primitive types and null. * <p> * For performance and overhead reasons, this should should limit to a safe production of a short * {@code String} (as large renderings will bloat up the stacktrace). Prefer to try/catch({@code Throwable}) * all code inside this method implementation. * <p> * If a {@code Throwable} is caught when rendering, this will fallback to the item's classname suffixed by * {@value #ERROR_IN_RENDERING_SUFFIX}. * * @param item the last emitted item, that caused the exception wrapped in * {@code OnErrorThrowable.OnNextValue} * @return a short {@link String} representation of the item if one is known for its type, or null for * default * @throws InterruptedException if the rendering thread is interrupted * @since (if this graduates from Experimental/Beta to supported, replace this parenthetical with the * release number) */ @Experimental protected String render (Object item) throws InterruptedException { //do nothing by default return null; } }