<commit_before>import { getApiError } from '@proton/shared/lib/api/helpers/apiErrorHelper';
import { wait } from '@proton/shared/lib/helpers/promise';
import noop from '@proton/utils/noop';
import { deleteVersionCookies } from '../../hooks/useEarlyAccess';
import { setCurrentRetries } from '../../helpers/earlyAccessDesynchronization';

const API_ERROR_KEY = 'API_ERROR_REFRESH';
const EARLY_ACCESS_KEY = 'EARLY_ACCESS_RESET';

export const clearAutomaticErrorRefresh = () => {
    sessionStorage.removeItem(API_ERROR_KEY);
    sessionStorage.removeItem(EARLY_ACCESS_KEY);
};

const handleEarlyAccessRefresh = () => {
    const oldValue = Number(sessionStorage.getItem(EARLY_ACCESS_KEY));
    // If it's the first time, we try a simple reload.
    if (!oldValue) {
        sessionStorage.setItem(EARLY_ACCESS_KEY, '1');
        window.location.reload();
        return true;
    }
    // If this error happens a second time, we force delete everything regarding version cookie and attempt another reload.
    if (oldValue === 1) {
        sessionStorage.setItem(EARLY_ACCESS_KEY, '2');
        deleteVersionCookies();
        setCurrentRetries(2);
        window.location.reload();
        return true;
    }
    return false;
};

const handleApiErrorRefresh = () => {
    if (!sessionStorage.getItem(API_ERROR_KEY)) {
        sessionStorage.setItem(API_ERROR_KEY, 'true');
        window.location.reload();
        return true;
    }
    return false;
};

const handleError = (error: any) => {
    const apiError = getApiError(error);
    // If there is no API error message or it's a chunk loading error, assume it's a resource loading error.
    if (!apiError.message || error?.message.contains('chunk')) {
        if (handleEarlyAccessRefresh()) {
            return true;
        }
    } else if (apiError.message) {
        if (handleApiErrorRefresh()) {
            return true;
        }
    }
    return false;
};

export const wrapUnloadError = <T>(promise: Promise<T>) => {
    // In Firefox, navigation events cancel ongoing network requests. This triggers the error handler and error
    // screen to be displayed. We set up a 'beforeunload' listener to detect unload to not unnecessarily
    // show cancelled network requests errors as fatal errors, and keep showing the loader screen instead.
    let unloaded = false;

    const handleUnload = () => {
        unloaded = true;
    };

    const listen = () => {
        window.addEventListener('beforeunload', handleUnload);
        return () => {
            window.removeEventListener('beforeunload', handleUnload);
        };
    };

    const unlisten = listen();

    return promise
        .then((result) => {
            clearAutomaticErrorRefresh();
            unlisten();
            return result;
        })
        .catch(async (e) => {
            // Wait an arbitrary amount of time to ensure the unload listener is first.
            await wait(3000);
            unlisten();
            // Never resolve the promise if the browser has unloaded or if we're refreshing
            if (unloaded || handleError(e)) {
                return new Promise(noop);
            }
            throw e;
        });
};
<commit_msg>Remove faulty contains<commit_after>import { getApiError } from '@proton/shared/lib/api/helpers/apiErrorHelper';
import { wait } from '@proton/shared/lib/helpers/promise';
import noop from '@proton/utils/noop';
import { deleteVersionCookies } from '../../hooks/useEarlyAccess';
import { setCurrentRetries } from '../../helpers/earlyAccessDesynchronization';

const API_ERROR_KEY = 'API_ERROR_REFRESH';
const EARLY_ACCESS_KEY = 'EARLY_ACCESS_RESET';

export const clearAutomaticErrorRefresh = () => {
    sessionStorage.removeItem(API_ERROR_KEY);
    sessionStorage.removeItem(EARLY_ACCESS_KEY);
};

const handleEarlyAccessRefresh = () => {
    const oldValue = Number(sessionStorage.getItem(EARLY_ACCESS_KEY));
    // If it's the first time, we try a simple reload.
    if (!oldValue) {
        sessionStorage.setItem(EARLY_ACCESS_KEY, '1');
        window.location.reload();
        return true;
    }
    // If this error happens a second time, we force delete everything regarding version cookie and attempt another reload.
    if (oldValue === 1) {
        sessionStorage.setItem(EARLY_ACCESS_KEY, '2');
        deleteVersionCookies();
        setCurrentRetries(2);
        window.location.reload();
        return true;
    }
    return false;
};

const handleApiErrorRefresh = () => {
    if (!sessionStorage.getItem(API_ERROR_KEY)) {
        sessionStorage.setItem(API_ERROR_KEY, 'true');
        window.location.reload();
        return true;
    }
    return false;
};

const handleError = (error: any) => {
    const apiError = getApiError(error);
    // If there is no API error message or it's a chunk loading error, assume it's a resource loading error.
    if (!apiError.message || error?.message?.includes('chunk')) {
        if (handleEarlyAccessRefresh()) {
            return true;
        }
    } else if (apiError.message) {
        if (handleApiErrorRefresh()) {
            return true;
        }
    }
    return false;
};

export const wrapUnloadError = <T>(promise: Promise<T>) => {
    // In Firefox, navigation events cancel ongoing network requests. This triggers the error handler and error
    // screen to be displayed. We set up a 'beforeunload' listener to detect unload to not unnecessarily
    // show cancelled network requests errors as fatal errors, and keep showing the loader screen instead.
    let unloaded = false;

    const handleUnload = () => {
        unloaded = true;
    };

    const listen = () => {
        window.addEventListener('beforeunload', handleUnload);
        return () => {
            window.removeEventListener('beforeunload', handleUnload);
        };
    };

    const unlisten = listen();

    return promise
        .then((result) => {
            clearAutomaticErrorRefresh();
            unlisten();
            return result;
        })
        .catch(async (e) => {
            // Wait an arbitrary amount of time to ensure the unload listener is first.
            await wait(3000);
            unlisten();
            // Never resolve the promise if the browser has unloaded or if we're refreshing
            if (unloaded || handleError(e)) {
                return new Promise(noop);
            }
            throw e;
        });
};

{'fraction_non_alphanumeric': 0.10991580916744621, 'fraction_numerical': 0.002494543186778921, 'mean_word_length': 2.6140845070422536, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 27, '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': '3428686', 'n_tokens_mistral': 1758, 'n_tokens_neox': 1728, 'n_words': 502}