<commit_before>import { ErrorIds } from './../models/error-ids';
import { ErrorEvent, ErrorType } from './../models/error-event';
import { PortalResources } from './../models/portal-resources';
import { AiService } from './ai.service';
import { TranslateService } from 'ng2-translate';
import { BroadcastService } from './broadcast.service';
import { ArmService } from './arm.service';
import { Observable } from 'rxjs/Rx';
import { FunctionsResponse } from './../models/functions-response';
import { Injectable } from '@angular/core';
import { Http, Request, Response, RequestOptionsArgs, ResponseType, ConnectionBackend, RequestOptions } from '@angular/http';
import { BroadcastEvent } from '../models/broadcast-event';

@Injectable()
export class FunctionsHttpService {

    constructor(private _http: Http,
                private _armService: ArmService,
                private _broadcastService: BroadcastService,
                private _translateService: TranslateService,
                private _aiService: AiService) {

    }

    request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
        let urlString = typeof url === 'string' ? url : url.url;
        return this._http.request(url, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(urlString));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `get` http method.
     */
    get(url: string, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.get(url, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `post` http method.
     */
    post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.post(url, body, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `put` http method.
     */
    put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.put(url, body, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `delete` http method.
     */
    delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.delete(url, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `patch` http method.
     */
    patch(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.patch(url, body, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `head` http method.
     */
    head(url: string, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.head(url, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `options` http method.
     */
    options(url: string, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.options(url, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    private checkCorsError(error: FunctionsResponse): Observable<any> {
        return this._http.get('/api/ping')
            .catch(e => {
                if (!error.isHandled) {
                    this._broadcastService.broadcast<ErrorEvent>(BroadcastEvent.Error, {
                        message: this._translateService.instant(PortalResources.error_appOffline),
                        errorId: ErrorIds.applicationOffline,
                        errorType: ErrorType.Fatal
                    });
                    error.isHandled = true;
                }
                throw error;
            })
            .flatMap(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
                if (!error.isHandled && error.status === 0 && error.type === ResponseType.Error) {
                    this._broadcastService.broadcast<ErrorEvent>(BroadcastEvent.Error, {
                        message: this._translateService.instant(PortalResources.error_CORSNotConfigured, { origin: window.location.origin }),
                        details: JSON.stringify(error),
                        errorId: ErrorIds.corsNotConfigured + this.getHostname(error.url),
                        errorType: ErrorType.RuntimeError
                    });
                    error.isHandled = true;
                }
                throw error;
            });
    }

    private getHostname(url: string): string {
        let anchor = document.createElement('a');
        anchor.setAttribute('href', url);
        let link = anchor.hostname;
        anchor = null;
        return link;
    }
}<commit_msg>Better categorization of CORS errors.<commit_after>import { ErrorIds } from './../models/error-ids';
import { ErrorEvent, ErrorType } from './../models/error-event';
import { PortalResources } from './../models/portal-resources';
import { AiService } from './ai.service';
import { TranslateService } from 'ng2-translate';
import { BroadcastService } from './broadcast.service';
import { ArmService } from './arm.service';
import { Observable } from 'rxjs/Rx';
import { FunctionsResponse } from './../models/functions-response';
import { Injectable } from '@angular/core';
import { Http, Request, Response, RequestOptionsArgs, ResponseType, ConnectionBackend, RequestOptions } from '@angular/http';
import { BroadcastEvent } from '../models/broadcast-event';
import { GlobalStateService } from "./global-state.service";

@Injectable()
export class FunctionsHttpService {

    constructor(private _http: Http,
                private _armService: ArmService,
                private _broadcastService: BroadcastService,
                private _globalStateService: GlobalStateService,
                private _translateService: TranslateService,
                private _aiService: AiService) {

    }

    request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
        let urlString = typeof url === 'string' ? url : url.url;
        return this._http.request(url, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(urlString));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `get` http method.
     */
    get(url: string, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.get(url, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `post` http method.
     */
    post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.post(url, body, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `put` http method.
     */
    put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.put(url, body, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `delete` http method.
     */
    delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.delete(url, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `patch` http method.
     */
    patch(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.patch(url, body, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `head` http method.
     */
    head(url: string, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.head(url, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    /**
     * Performs a request with `options` http method.
     */
    options(url: string, options?: RequestOptionsArgs): Observable<Response> {
        return this._http.options(url, options)
            .catch(e => this.checkCorsError(e))
            .do(_ => {
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.corsNotConfigured + this.getHostname(url));
                this._broadcastService.broadcast<string>(BroadcastEvent.ClearError, ErrorIds.applicationOffline);
            });
    }

    private checkCorsError(error: FunctionsResponse): Observable<any> {
        if (error.status === 0 && error.type === ResponseType.Error) {
            return this._http.get('/api/ping')
                .catch(e => {
                    if (!error.isHandled) {
                        this._broadcastService.broadcast<ErrorEvent>(BroadcastEvent.Error, {
                            message: this._translateService.instant(PortalResources.error_appOffline),
                            errorId: ErrorIds.applicationOffline,
                            errorType: ErrorType.Fatal
                        });
                        error.isHandled = true;
                    }
                    throw error;
                })
                .flatMap(_ => {
                    if (this._globalStateService.FunctionContainer && this._globalStateService.FunctionContainer.id) {
                        return this._armService.getConfig(this._globalStateService.FunctionContainer)
                            .do(config => {
                                let cors: { allowedOrigins: string[] } = <any>config['cors'];
                                let isConfigured = (cors && cors.allowedOrigins && cors.allowedOrigins.length > 0)
                                    ? !!cors.allowedOrigins.find(o => o.toLocaleLowerCase() === window.location.origin)
                                    : false;
                                if (!isConfigured) {
                                    this._broadcastService.broadcast<ErrorEvent>(BroadcastEvent.Error, {
                                        message: this._translateService.instant(PortalResources.error_CORSNotConfigured, { origin: window.location.origin }),
                                        details: JSON.stringify(error),
                                        errorId: ErrorIds.corsNotConfigured + this.getHostname(error.url),
                                        errorType: ErrorType.RuntimeError
                                    });
                                    error.isHandled = true;
                                }
                                throw error;
                            }, err => {
                                throw error;
                            });
                    } else {
                        throw error;
                    }
                });
        } else {
            throw error;
        }
    }

    private getHostname(url: string): string {
        let anchor = document.createElement('a');
        anchor.setAttribute('href', url);
        let link = anchor.hostname;
        anchor = null;
        return link;
    }
}
{'fraction_non_alphanumeric': 0.11416213382266203, 'fraction_numerical': 0.00032767547021429977, 'mean_word_length': 2.162038955656859, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 99, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 13, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7323776', 'n_tokens_mistral': 3980, 'n_tokens_neox': 3860, 'n_words': 698}