<commit_before>import 'whatwg-fetch';

export const HTTPREQUEST_CLEAR = 'HTTPREQUEST_CLEAR';
export const STATE_PENDING = 'STATE_PENDING';
export const STATE_COMPLETE = 'STATE_COMPLETE';
export const STATE_FAILED = 'STATE_FAILED';

let actions = {};

actions._fetch = (...args) => fetch(...args);

actions.request = (params = {}) => {
    const {
        baseUrl,
        headers,
        method = 'GET',
        path = '',
        query = {},
        body,
        preserve = false
        // priority = 3
    } = params;
    const requestId = params.requestId || `${method} ${path || '/'}`;
    const subject = params.subject || requestId.replace(' ', '_').replace('/', '_');

    return async (dispatch, getState) => {
        const url = baseUrl
            .concat(path)
            .concat(Object.keys(query).length > 0 ?
                '?' + Object.keys(query)
                    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(query[key])}`)
                    .join('&')
                :
                '');

        dispatch({
            type: `HTTPREQUEST_${subject}_INITIATE`,
            requestId,
            params
        });

        let fetchHeaders = new Headers();
        if (headers) {
            for (let name in headers) {
                fetchHeaders.append(name, headers[name]);
            }
        }

        const res = await actions
            ._fetch(url, {
                headers: fetchHeaders,
                method: method || 'GET',
                body: body ? JSON.stringify(body) : undefined,
                credentials: 'include'
            })
            .catch(e => {
                let error = new Error('Can\'t connect to url.');
                error.details = e.message;
                error.type = 'ConnectionError';
                throw error;
            });

        const contentType = res.headers.get('Content-Type');
        const status = res.status;

        const isJson = Boolean(contentType && (
            contentType.includes('application/json') || contentType.includes('application/hal+json')
        ));

        if (status >= 200 && status <= 290) {
            // Success response
            const response = await (isJson ? res.json() : res.text());

            dispatch({
                type: `HTTPREQUEST_${subject}_COMPLETE`,
                receivedAt: (new Date()).toISOString(),
                requestId,
                status,
                response,
                params
            });

            return {
                status,
                // When preserving data, it should be read from the state
                response: preserve ? null : response
            };

        } else {
            // Error
            if (isJson) {
                const body = await res.json();

                // Parse error response
                let error = new Error(body.message || res.statusText);
                error.status = status || body.status;
                if (body.details) {
                    error.details = body.details;
                }

                // throw error;
                dispatch({
                    type: `HTTPREQUEST_${subject}_ERROR`,
                    requestId,
                    params,
                    error
                });

                throw error;

            } else {
                // Error response
                let error = new Error(res.statusText || 'Unknown request error');
                error.status = status;

                // throw error;
                dispatch({
                    type: `HTTPREQUEST_${subject}_ERROR`,
                    requestId,
                    params,
                    error
                });

                throw error;
            }
        }
    };
};
<commit_msg>Dispatch error on connection failure<commit_after>import 'whatwg-fetch';

export const HTTPREQUEST_CLEAR = 'HTTPREQUEST_CLEAR';
export const STATE_PENDING = 'STATE_PENDING';
export const STATE_COMPLETE = 'STATE_COMPLETE';
export const STATE_FAILED = 'STATE_FAILED';

let actions = {};

actions._fetch = (...args) => fetch(...args);

actions.request = (params = {}) => {
    const {
        baseUrl,
        headers,
        method = 'GET',
        path = '',
        query = {},
        body,
        preserve = false
        // priority = 3
    } = params;
    const requestId = params.requestId || `${method} ${path || '/'}`;
    const subject = params.subject || requestId.replace(' ', '_').replace('/', '_');

    return async (dispatch, getState) => {
        const url = baseUrl
            .concat(path)
            .concat(Object.keys(query).length > 0 ?
                '?' + Object.keys(query)
                    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(query[key])}`)
                    .join('&')
                :
                '');

        dispatch({
            type: `HTTPREQUEST_${subject}_INITIATE`,
            requestId,
            params
        });

        let fetchHeaders = new Headers();
        if (headers) {
            for (let name in headers) {
                fetchHeaders.append(name, headers[name]);
            }
        }

        const res = await actions
            ._fetch(url, {
                headers: fetchHeaders,
                method: method || 'GET',
                body: body ? JSON.stringify(body) : undefined,
                credentials: 'include'
            })
            .catch(e => {
                let error = new Error('Can\'t connect to url.');
                error.details = e.message;
                error.type = 'ConnectionError';

                dispatch({
                    type: `HTTPREQUEST_${subject}_ERROR`,
                    requestId,
                    params,
                    error
                });
            });

        const contentType = res.headers.get('Content-Type');
        const status = res.status;

        const isJson = Boolean(contentType && (
            contentType.includes('application/json') || contentType.includes('application/hal+json')
        ));

        if (status >= 200 && status <= 290) {
            // Success response
            const response = await (isJson ? res.json() : res.text());

            dispatch({
                type: `HTTPREQUEST_${subject}_COMPLETE`,
                receivedAt: (new Date()).toISOString(),
                requestId,
                status,
                response,
                params
            });

            return {
                status,
                // When preserving data, it should be read from the state
                response: preserve ? null : response
            };

        } else {
            // Error
            if (isJson) {
                const body = await res.json();

                // Parse error response
                let error = new Error(body.message || res.statusText);
                error.status = status || body.status;
                if (body.details) {
                    error.details = body.details;
                }

                dispatch({
                    type: `HTTPREQUEST_${subject}_ERROR`,
                    requestId,
                    status,
                    params,
                    error
                });

            } else {
                // Error response
                let error = new Error(res.statusText || 'Unknown request error');
                error.status = status;

                dispatch({
                    type: `HTTPREQUEST_${subject}_ERROR`,
                    requestId,
                    status,
                    params,
                    error
                });
            }
        }
    };
};

{'fraction_non_alphanumeric': 0.11554921540656206, 'fraction_numerical': 0.0020749578524186228, 'mean_word_length': 1.2192805755395684, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 17, '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': '2304195', 'n_tokens_mistral': 1930, 'n_tokens_neox': 1801, 'n_words': 432}