Add copy endpoint to ArchiveController

Co-authored-by: Jonathan Klabunde Tomer <125505367+jkt-signal@users.noreply.github.com>
Co-authored-by: Chris Eager <79161849+eager-signal@users.noreply.github.com>
This commit is contained in:
ravi-signal
2023-11-28 11:45:41 -06:00
committed by GitHub
parent 1da3f96d10
commit 202dd8e92d
24 changed files with 1918 additions and 248 deletions

View File

@@ -1,13 +1,14 @@
package org.whispersystems.textsecuregcm.util;
import java.util.concurrent.CompletionException;
import java.util.function.Function;
public final class ExceptionUtils {
private ExceptionUtils() {
// utility class
}
/**
* Extracts the cause of a {@link CompletionException}. If the given {@code throwable} is a
* {@code CompletionException}, this method will recursively iterate through its causal chain until it finds the first
@@ -16,7 +17,6 @@ public final class ExceptionUtils {
* {@code throwable} is not a {@code CompletionException}, then this method returns the original {@code throwable}.
*
* @param throwable the throwable to "unwrap"
*
* @return the first entity in the given {@code throwable}'s causal chain that is not a {@code CompletionException}
*/
public static Throwable unwrap(Throwable throwable) {
@@ -27,8 +27,8 @@ public final class ExceptionUtils {
}
/**
* Wraps the given {@code throwable} in a {@link CompletionException} unless the given {@code throwable} is already
* a {@code CompletionException}, in which case this method returns the original throwable.
* Wraps the given {@code throwable} in a {@link CompletionException} unless the given {@code throwable} is already a
* {@code CompletionException}, in which case this method returns the original throwable.
*
* @param throwable the throwable to wrap in a {@code CompletionException}
*/
@@ -37,4 +37,29 @@ public final class ExceptionUtils {
? completionException
: new CompletionException(throwable);
}
/**
* Create a handler suitable for use with {@link java.util.concurrent.CompletionStage#exceptionally} that only handles
* a specific exception subclass.
*
* @param exceptionType The class of exception that will be handled
* @param fn A function that handles exceptions of type exceptionType
* @param <T> The type of the stage that will be mapped
* @param <E> The type of the exception that will be handled
* @return A function suitable for use with {@link java.util.concurrent.CompletionStage#exceptionally}
*/
public static <T, E extends Throwable> Function<Throwable, ? extends T> exceptionallyHandler(
final Class<E> exceptionType,
final Function<E, ? extends T> fn) {
return anyException -> {
if (exceptionType.isInstance(anyException)) {
return fn.apply(exceptionType.cast(anyException));
}
final Throwable unwrap = unwrap(anyException);
if (exceptionType.isInstance(unwrap)) {
return fn.apply(exceptionType.cast(unwrap));
}
throw wrap(anyException);
};
}
}