一、前言
关于flink-core源码包中的org.apache.flink.util.ExceptionUtils异常工具类,对报出异常Throwable类型进行转换处理等。
二、源码说明
package org.apache.flink.util;@b@@b@import org.apache.flink.annotation.Internal;@b@import javax.annotation.Nullable;@b@import java.io.IOException;@b@import java.io.PrintWriter;@b@import java.io.StringWriter;@b@import java.util.Optional;@b@import java.util.concurrent.CompletionException;@b@import java.util.concurrent.ExecutionException;@b@import static org.apache.flink.util.Preconditions.checkNotNull;@b@@b@/**@b@ * A collection of utility functions for dealing with exceptions and exception workflows.@b@ */@b@@Internal@b@public final class ExceptionUtils {@b@@b@ /** The stringified representation of a null exception reference */ @b@ public static final String STRINGIFIED_NULL_EXCEPTION = "(null)";@b@@b@ /**@b@ * Makes a string representation of the exception's stack trace, or "(null)", if the@b@ * exception is null.@b@ * @b@ * This method makes a best effort and never fails.@b@ * @b@ * @param e The exception to stringify.@b@ * @return A string with exception name and call stack.@b@ */@b@ public static String stringifyException(final Throwable e) {@b@ if (e == null) {@b@ return STRINGIFIED_NULL_EXCEPTION;@b@ }@b@ @b@ try {@b@ StringWriter stm = new StringWriter();@b@ PrintWriter wrt = new PrintWriter(stm);@b@ e.printStackTrace(wrt);@b@ wrt.close();@b@ return stm.toString();@b@ }@b@ catch (Throwable t) {@b@ return e.getClass().getName() + " (error while printing stack trace)";@b@ }@b@ }@b@@b@ /**@b@ * Checks whether the given exception indicates a situation that may leave the@b@ * JVM in a corrupted state, meaning a state where continued normal operation can only be@b@ * guaranteed via clean process restart.@b@ *@b@ * <p>Currently considered fatal exceptions are Virtual Machine errors indicating@b@ * that the JVM is corrupted, like {@link InternalError}, {@link UnknownError},@b@ * and {@link java.util.zip.ZipError} (a special case of InternalError).@b@ *@b@ * @param t The exception to check.@b@ * @return True, if the exception is considered fatal to the JVM, false otherwise.@b@ */@b@ public static boolean isJvmFatalError(Throwable t) {@b@ return (t instanceof InternalError) || (t instanceof UnknownError);@b@ }@b@@b@ /**@b@ * Checks whether the given exception indicates a situation that may leave the@b@ * JVM in a corrupted state, or an out-of-memory error.@b@ * @b@ * <p>See {@link ExceptionUtils#isJvmFatalError(Throwable)} for a list of fatal JVM errors.@b@ * This method additionally classifies the {@link OutOfMemoryError} as fatal, because it@b@ * may occur in any thread (not the one that allocated the majority of the memory) and thus@b@ * is often not recoverable by destroying the particular thread that threw the exception.@b@ * @b@ * @param t The exception to check.@b@ * @return True, if the exception is fatal to the JVM or and OutOfMemoryError, false otherwise.@b@ */@b@ public static boolean isJvmFatalOrOutOfMemoryError(Throwable t) {@b@ return isJvmFatalError(t) || t instanceof OutOfMemoryError;@b@ }@b@@b@ /**@b@ * Rethrows the given {@code Throwable}, if it represents an error that is fatal to the JVM.@b@ * See {@link ExceptionUtils#isJvmFatalError(Throwable)} for a definition of fatal errors.@b@ * @b@ * @param t The Throwable to check and rethrow.@b@ */@b@ public static void rethrowIfFatalError(Throwable t) {@b@ if (isJvmFatalError(t)) {@b@ throw (Error) t;@b@ }@b@ }@b@@b@ /**@b@ * Rethrows the given {@code Throwable}, if it represents an error that is fatal to the JVM@b@ * or an out-of-memory error. See {@link ExceptionUtils#isJvmFatalError(Throwable)} for a@b@ * definition of fatal errors.@b@ *@b@ * @param t The Throwable to check and rethrow.@b@ */@b@ public static void rethrowIfFatalErrorOrOOM(Throwable t) {@b@ if (isJvmFatalError(t) || t instanceof OutOfMemoryError) {@b@ throw (Error) t;@b@ }@b@ }@b@@b@ /**@b@ * Adds a new exception as a {@link Throwable#addSuppressed(Throwable) suppressed exception}@b@ * to a prior exception, or returns the new exception, if no prior exception exists.@b@ *@b@ * <pre>{@code@b@ *@b@ * public void closeAllThings() throws Exception {@b@ * Exception ex = null;@b@ * try {@b@ * component.shutdown();@b@ * } catch (Exception e) {@b@ * ex = firstOrSuppressed(e, ex);@b@ * }@b@ * try {@b@ * anotherComponent.stop();@b@ * } catch (Exception e) {@b@ * ex = firstOrSuppressed(e, ex);@b@ * }@b@ * try {@b@ * lastComponent.shutdown();@b@ * } catch (Exception e) {@b@ * ex = firstOrSuppressed(e, ex);@b@ * }@b@ *@b@ * if (ex != null) {@b@ * throw ex;@b@ * }@b@ * }@b@ * }</pre>@b@ *@b@ * @param newException The newly occurred exception@b@ * @param previous The previously occurred exception, possibly null.@b@ *@b@ * @return The new exception, if no previous exception exists, or the previous exception with the@b@ * new exception in the list of suppressed exceptions.@b@ */@b@ public static <T extends Throwable> T firstOrSuppressed(T newException, @Nullable T previous) {@b@ checkNotNull(newException, "newException");@b@@b@ if (previous == null) {@b@ return newException;@b@ } else {@b@ previous.addSuppressed(newException);@b@ return previous;@b@ }@b@ }@b@@b@ /**@b@ * Throws the given {@code Throwable} in scenarios where the signatures do not allow you to@b@ * throw an arbitrary Throwable. Errors and RuntimeExceptions are thrown directly, other exceptions@b@ * are packed into runtime exceptions@b@ * @b@ * @param t The throwable to be thrown.@b@ */@b@ public static void rethrow(Throwable t) {@b@ if (t instanceof Error) {@b@ throw (Error) t;@b@ }@b@ else if (t instanceof RuntimeException) {@b@ throw (RuntimeException) t;@b@ }@b@ else {@b@ throw new RuntimeException(t);@b@ }@b@ }@b@ @b@ /**@b@ * Throws the given {@code Throwable} in scenarios where the signatures do not allow you to@b@ * throw an arbitrary Throwable. Errors and RuntimeExceptions are thrown directly, other exceptions@b@ * are packed into a parent RuntimeException.@b@ * @b@ * @param t The throwable to be thrown.@b@ * @param parentMessage The message for the parent RuntimeException, if one is needed.@b@ */@b@ public static void rethrow(Throwable t, String parentMessage) {@b@ if (t instanceof Error) {@b@ throw (Error) t;@b@ }@b@ else if (t instanceof RuntimeException) {@b@ throw (RuntimeException) t;@b@ }@b@ else {@b@ throw new RuntimeException(parentMessage, t);@b@ }@b@ }@b@@b@ /**@b@ * Throws the given {@code Throwable} in scenarios where the signatures do allow to@b@ * throw a Exception. Errors and Exceptions are thrown directly, other "exotic"@b@ * subclasses of Throwable are wrapped in an Exception.@b@ *@b@ * @param t The throwable to be thrown.@b@ * @param parentMessage The message for the parent Exception, if one is needed.@b@ */@b@ public static void rethrowException(Throwable t, String parentMessage) throws Exception {@b@ if (t instanceof Error) {@b@ throw (Error) t;@b@ }@b@ else if (t instanceof Exception) {@b@ throw (Exception) t;@b@ }@b@ else {@b@ throw new Exception(parentMessage, t);@b@ }@b@ }@b@@b@ /**@b@ * Tries to throw the given {@code Throwable} in scenarios where the signatures allows only IOExceptions@b@ * (and RuntimeException and Error). Throws this exception directly, if it is an IOException,@b@ * a RuntimeException, or an Error. Otherwise does nothing.@b@ *@b@ * @param t The Throwable to be thrown.@b@ */@b@ public static void tryRethrowIOException(Throwable t) throws IOException {@b@ if (t instanceof IOException) {@b@ throw (IOException) t;@b@ }@b@ else if (t instanceof RuntimeException) {@b@ throw (RuntimeException) t;@b@ }@b@ else if (t instanceof Error) {@b@ throw (Error) t;@b@ }@b@ }@b@@b@ /**@b@ * Re-throws the given {@code Throwable} in scenarios where the signatures allows only IOExceptions@b@ * (and RuntimeException and Error).@b@ * @b@ * Throws this exception directly, if it is an IOException, a RuntimeException, or an Error. Otherwise it @b@ * wraps it in an IOException and throws it.@b@ * @b@ * @param t The Throwable to be thrown.@b@ */@b@ public static void rethrowIOException(Throwable t) throws IOException {@b@ if (t instanceof IOException) {@b@ throw (IOException) t;@b@ }@b@ else if (t instanceof RuntimeException) {@b@ throw (RuntimeException) t;@b@ }@b@ else if (t instanceof Error) {@b@ throw (Error) t;@b@ }@b@ else {@b@ throw new IOException(t.getMessage(), t);@b@ }@b@ }@b@@b@ /**@b@ * Checks whether a throwable chain contains a specific type of exception and returns it.@b@ *@b@ * @param throwable the throwable chain to check.@b@ * @param searchType the type of exception to search for in the chain.@b@ * @return Optional throwable of the requested type if available, otherwise empty@b@ */@b@ public static Optional<Throwable> findThrowable(Throwable throwable, Class<?> searchType) {@b@ if (throwable == null || searchType == null) {@b@ return Optional.empty();@b@ }@b@@b@ Throwable t = throwable;@b@ while (t != null) {@b@ if (searchType.isAssignableFrom(t.getClass())) {@b@ return Optional.of(t);@b@ } else {@b@ t = t.getCause();@b@ }@b@ }@b@@b@ return Optional.empty();@b@ }@b@@b@ /**@b@ * Checks whether a throwable chain contains a specific error message and returns the corresponding throwable.@b@ *@b@ * @param throwable the throwable chain to check.@b@ * @param searchMessage the error message to search for in the chain.@b@ * @return Optional throwable containing the search message if available, otherwise empty@b@ */@b@ public static Optional<Throwable> findThrowableWithMessage(Throwable throwable, String searchMessage) {@b@ if (throwable == null || searchMessage == null) {@b@ return Optional.empty();@b@ }@b@@b@ Throwable t = throwable;@b@ while (t != null) {@b@ if (t.getMessage().contains(searchMessage)) {@b@ return Optional.of(t);@b@ } else {@b@ t = t.getCause();@b@ }@b@ }@b@@b@ return Optional.empty();@b@ }@b@@b@ /**@b@ * Unpacks an {@link ExecutionException} and returns its cause. Otherwise the given@b@ * Throwable is returned.@b@ *@b@ * @param throwable to unpack if it is an ExecutionException@b@ * @return Cause of ExecutionException or given Throwable@b@ */@b@ public static Throwable stripExecutionException(Throwable throwable) {@b@ while (throwable instanceof ExecutionException && throwable.getCause() != null) {@b@ throwable = throwable.getCause();@b@ }@b@@b@ return throwable;@b@ }@b@@b@ /**@b@ * Unpacks an {@link CompletionException} and returns its cause. Otherwise the given@b@ * Throwable is returned.@b@ *@b@ * @param throwable to unpack if it is an CompletionException@b@ * @return Cause of CompletionException or given Throwable@b@ */@b@ public static Throwable stripCompletionException(Throwable throwable) {@b@ while (throwable instanceof CompletionException && throwable.getCause() != null) {@b@ throwable = throwable.getCause();@b@ }@b@@b@ return throwable;@b@ }@b@@b@ /**@b@ * Tries to find a {@link SerializedThrowable} as the cause of the given throwable and throws its@b@ * deserialized value. If there is no such throwable, then the original throwable is thrown.@b@ *@b@ * @param throwable to check for a SerializedThrowable@b@ * @param classLoader to be used for the deserialization of the SerializedThrowable@b@ * @throws Throwable either the deserialized throwable or the given throwable@b@ */@b@ public static void tryDeserializeAndThrow(Throwable throwable, ClassLoader classLoader) throws Throwable {@b@ Throwable current = throwable;@b@@b@ while (!(current instanceof SerializedThrowable) && current.getCause() != null) {@b@ current = current.getCause();@b@ }@b@@b@ if (current instanceof SerializedThrowable) {@b@ throw ((SerializedThrowable) current).deserializeError(classLoader);@b@ } else {@b@ throw throwable;@b@ }@b@ }@b@@b@ // ------------------------------------------------------------------------@b@@b@ /** Private constructor to prevent instantiation. */@b@ private ExceptionUtils() {}@b@}