<commit_before>package org.pac4j.async.core.exception.handler;

import org.pac4j.core.exception.HttpAction;

import java.util.concurrent.CompletionException;
import java.util.function.Consumer;

/**
 * Simple exception unwrapper for CompletionExeeptions to unwrap the underlying exception where more than one
 * CompletionStage may be involved.
 */
public class AsyncExceptionHandler {

    public static void handleException(final Throwable t, final Consumer<Throwable> unwrappedThrowableHandler) {
        unwrappedThrowableHandler.accept(unwrapAsyncException(t));
    }

    public static HttpAction extractAsyncHttpAction(final HttpAction action, final Throwable t) throws Throwable {

        final Throwable unwrapped = unwrapAsyncException(t);
        final HttpAction result = action != null ? action : (unwrapped instanceof HttpAction ? (HttpAction) unwrapped : null);
        if (result != null) {
            return result;
        } else throw unwrapped;
    }

    private static Throwable unwrapAsyncException(final Throwable t) {
        return (t instanceof CompletionException) ? t.getCause() : t;

    }

}<commit_msg>pac4j-async-170 Introduce Pac4jExceptionHandler interface for dealing with async exceptions<commit_after>package org.pac4j.async.core.exception.handler;

import org.pac4j.async.core.context.AsyncWebContext;
import org.pac4j.core.exception.HttpAction;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.function.Consumer;

/**
 * Simple exception handling for CompletionExeeptions to unwrap the underlying exception where more than one
 * CompletionStage may be involved.
 */
public interface AsyncExceptionHandler<T> {

    static void handleException(final Throwable t, final Consumer<Throwable> unwrappedThrowableHandler) {
        unwrappedThrowableHandler.accept(unwrapAsyncException(t));
    }

    static HttpAction extractAsyncHttpAction(final HttpAction action, final Throwable t) throws Throwable {

        final Throwable unwrapped = unwrapAsyncException(t);
        final HttpAction result = action != null ? action : (unwrapped instanceof HttpAction ? (HttpAction) unwrapped : null);
        if (result != null) {
            return result;
        } else throw unwrapped;
    }

    static Throwable unwrapAsyncException(final Throwable t) {
        return (t instanceof CompletionException) ? t.getCause() : t;
    }

    /**
     * Interface to be implemented to offer custom exception handling to completable futures returned by
     * logic (either security, callback or logout logic).
     *
     * A default implementation will be provided which offers use of a webContext's execution context. In addition
     * a "do nothing" implementation will be offered which permits external implementations to handle exceptions
     * in their own code rather than via injection of a handler into the relevant logic.
     * @param future
     * @return
     */
    CompletableFuture<T> applyExceptionHandling(final CompletableFuture<T> future, final AsyncWebContext webContext);

}
{'fraction_non_alphanumeric': 0.07052733743125202, 'fraction_numerical': 0.003235198964736331, 'mean_word_length': 4.035830618892508, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '835729', 'n_tokens_mistral': 802, 'n_tokens_neox': 767, 'n_words': 257}