All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.neo4j.internal.helpers.Exceptions Maven / Gradle / Ivy

There is a newer version: 2025.03.0
Show newest version
/*
 * Copyright (c) "Neo4j"
 * Neo4j Sweden AB [https://neo4j.com]
 *
 * This file is part of Neo4j.
 *
 * Neo4j is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.neo4j.internal.helpers;

import static org.neo4j.function.Predicates.instanceOfAny;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.State;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;

public final class Exceptions {
    public static final UncaughtExceptionHandler SILENT_UNCAUGHT_EXCEPTION_HANDLER = (t, e) -> { // Don't print about it
    };

    private Exceptions() {
        throw new AssertionError("No instances");
    }

    /**
     * Rethrows {@code exception} if it is an instance of {@link RuntimeException} or {@link Error}. Typical usage is:
     *
     * 
     * catch (Throwable e) {
     *   ......common code......
     *   throwIfUnchecked(e);
     *   throw new RuntimeException(e);
     * }
     * 
* * This will only wrap checked exception in a {@code RuntimeException}. Do note that if the segment {@code common code} * is missing, it's preferable to use this instead: * *
     * catch (RuntimeException | Error e) {
     *   throw e;
     * }
     * catch (Throwable e) {
     *   throw new RuntimeException(e);
     * }
     * 
* * @param exception to rethrow. */ public static void throwIfUnchecked(Throwable exception) { Objects.requireNonNull(exception); if (exception instanceof RuntimeException) { throw (RuntimeException) exception; } if (exception instanceof Error) { throw (Error) exception; } } /** * Will rethrow the provided {@code exception} if it is an instance of {@code clazz}. Typical usage is: * *
     * catch (Throwable e) {
     *   ......common code......
     *   throwIfInstanceOf(e, BarException.class);
     *   throw new RuntimeException(e);
     * }
     * 
* * This will filter out all {@code BarExceptions} and wrap the rest in {@code RuntimeException}. Do note that if the * segment {@code common code} is missing, it's preferable to use this instead: * *
     * catch (BarException e) {
     *   throw e;
     * } catch (Throwable e) {
     *   threw new RuntimeException(e);
     * }
     * 
* * @param exception to rethrow. * @param clazz a {@link Class} instance to check against. * @param type thrown, if thrown at all. * @throws T if {@code exception} is an instance of {@code clazz}. */ public static void throwIfInstanceOf(Throwable exception, Class clazz) throws T { Objects.requireNonNull(exception); if (clazz.isInstance(exception)) { throw clazz.cast(exception); } } /** * @see #throwIfInstanceOfOrUnchecked(Throwable, Class, Function) and the exception will be rethrown as a * {@link RuntimeException} if neither of the sought instance not unchecked. */ public static void throwIfInstanceOfOrUnchecked( Throwable exception, Class clazz) throws CHECKED { throwIfInstanceOfOrUnchecked(exception, clazz, RuntimeException::new); } /** * Will rethrow the provided {@code exception} as {@code CHECKED} if it's of that instance, * otherwise as-is if it's unchecked, or lastly converted with {@code fallback} as a {@code FALLBACK}. * @param exception the {@link Throwable} to rethrow. * @param clazz {@link Class} of the checked exception to check instance of. * @param fallback a way to convert the {@code exception} into a {@code FALLBACK} exception. * @param type of {@link Throwable} to check for (and rethrow) first. * @param type of {@link Throwable} that {@code fallback} will convert the {@code exception} into * if it doesn't fall into one of the other categories. * @throws CHECKED if the {@code exception} is of this type. * @throws FALLBACK if the {@code exception} is not of the {@code CHECKED} type, nor unchecked. */ public static void throwIfInstanceOfOrUnchecked( Throwable exception, Class clazz, Function fallback) throws CHECKED, FALLBACK { throwIfInstanceOf(exception, clazz); throwIfUnchecked(exception); throw fallback.apply(exception); } /** * Searches the entire exception hierarchy of causes and suppressed exceptions against the given predicate. * * @param e exception to start searching from. * @return the first exception found matching the predicate. */ public static Optional findCauseOrSuppressed(Throwable e, Predicate predicate) { if (e == null) { return Optional.empty(); } if (predicate.test(e)) { return Optional.of(e); } if (e.getCause() != null && e.getCause() != e) { Optional cause = findCauseOrSuppressed(e.getCause(), predicate); if (cause.isPresent()) { return cause; } } if (e.getSuppressed() != null) { for (Throwable suppressed : e.getSuppressed()) { if (suppressed == e) { continue; } Optional cause = findCauseOrSuppressed(suppressed, predicate); if (cause.isPresent()) { return cause; } } } return Optional.empty(); } public static StackTraceElement[] getPartialStackTrace(int from, int to) { return StackWalker.getInstance().walk(s -> s.skip(from) .limit(to - from) .map(StackWalker.StackFrame::toStackTraceElement) .toArray(StackTraceElement[]::new)); } public static String stringify(Throwable throwable) { if (throwable == null) { return null; } StringWriter stringWriter = new StringWriter(); throwable.printStackTrace(new PrintWriter(stringWriter)); return stringWriter.toString(); } public static String stringify(Thread thread, StackTraceElement[] elements) { StringBuilder builder = new StringBuilder() .append('"') .append(thread.getName()) .append('"') .append(thread.isDaemon() ? " daemon" : "") .append(" prio=") .append(thread.getPriority()) .append(" tid=") .append(thread.getId()) .append(' ') .append(thread.getState().name().toLowerCase(Locale.ROOT)) .append('\n'); builder.append(" ") .append(State.class.getName()) .append(": ") .append(thread.getState().name().toUpperCase(Locale.ROOT)) .append('\n'); for (StackTraceElement element : elements) { builder.append(" at ") .append(element.getClassName()) .append('.') .append(element.getMethodName()); if (element.isNativeMethod()) { builder.append("(Native method)"); } else if (element.getFileName() == null) { builder.append("(Unknown source)"); } else { builder.append('(') .append(element.getFileName()) .append(':') .append(element.getLineNumber()) .append(')'); } builder.append("\n"); } return builder.toString(); } public static boolean contains( final Throwable cause, final String containsMessage, final Class... anyOfTheseClasses) { final Predicate anyOfClasses = instanceOfAny(anyOfTheseClasses); return contains( cause, item -> item.getMessage() != null && item.getMessage().contains(containsMessage) && anyOfClasses.test(item)); } public static boolean contains(Throwable cause, Predicate toLookFor) { while (cause != null) { if (toLookFor.test(cause)) { return true; } cause = cause.getCause(); } return false; } public static T chain(T initial, T current) { if (initial == null) { return current; } if (current != null && initial != current) { initial.addSuppressed(current); } return initial; } public static EXCEPTION disguiseException( Class disguise, String message, Throwable disguised) { EXCEPTION exception; try { try { exception = disguise.getConstructor(String.class, Throwable.class).newInstance(message, disguised); } catch (NoSuchMethodException e) { exception = disguise.getConstructor(String.class).newInstance(message); try { exception.initCause(disguised); } catch (IllegalStateException ignored) { } } } catch (Exception e) { throw new Error( message + ". An exception of type " + disguise.getName() + " was requested to be thrown but that proved impossible", e); } return exception; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy