/**
  * This function handles automatic retry when 401 error happens.
  * The returned Observable throws errors with user friendly messages.
  */
 private withRetry(initialResult: Observable<Response>, func: (...params: any[]) => Observable<Response>, ...params: any[]): Observable<Response> {
     return initialResult
         .catch(error => {
             if (error.status === 401) {
                 this.authService.unauthenticated();     // 401 means authentication required
                 let message = this.authService.isOrgApiKeySet ? 'Incorrect organization API key' : 'Authentication is required';
                 return Observable.fromPromise(this.authService.login(message))
                     .mergeMap(confirmed => {
                         if (confirmed) { // logged in again, or updated api key
                             this.authService.authenticationMayChange();
                             switch (params.length) {
                                 case 1:
                                     return func(params[0]);
                                 case 2:
                                     return func(params[0], params[1]);
                                 case 3:
                                     return func(params[0], params[1], params[2]);
                                 default:
                                     return Observable.throw(new Error('Wrong number of parameters: ' + params));
                             }
                         }else {      // canceled
                             return Observable.throw(new Error('User cancelled authentication'));
                         }
                     });
             }else {
                 let errorDetail = error.json();
                 if (errorDetail) {
                     this.authService.authenticated();  // a valid API response received
                     return Observable.throw(new Error(errorDetail.type + ': ' + errorDetail.message));
                 }
                 console.log('API call failed: ' + JSON.stringify(error));
                 return Observable.throw(error);
             }
         });
 }
Beispiel #2
0
  intercept(observable: Observable<Response>): Observable<Response> {
    return observable.catch((err, source) => {
      if (err.status  === 401 && !_.endsWith(err.url, '/login')) {
          this._router.navigate(['login']);
          return Observable.empty(null);
        } else {
          return Observable.throw(err);
      }
    });

  }
Beispiel #3
0
    /**
     * Creates a new Reactive Command.
     * @param canRun An observable that determines whether the given task is allowed to run at a given moment.
     * @param task A function that returns an observable that represents the asynchronous operation.
     * @param scheduler The scheduler that all of the results should be observed on.
     */
    constructor(private task: (args: TArgs) => Observable<TResult>, private canRun: Observable<boolean>, private scheduler: Scheduler) {
        if (!task) {
            throw new Error("The task parameter must be supplied");
        }
        if (!canRun) {
            throw new Error("The canRun parameter must be supplied");
        }
        if (!scheduler) {
            throw new Error("The scheduler parameter must be supplied");
        }
        this._executionInfo = new Subject<ExecutionInfo<TResult>>();
        this._synchronizedExcecutionInfo = this._executionInfo;
        this._exceptions = new Subject<any>();

        // Implementation mostly taken from:
        // https://github.com/reactiveui/ReactiveUI/blob/rxui7-master/ReactiveUI/ReactiveCommand.cs#L628
        
        this._isExecuting = this._synchronizedExcecutionInfo
            .observeOn(scheduler)
            .map(info => info.demarcation === ExecutionDemarcation.Begin)
            .startWith(false)
            .distinctUntilChanged()
            .publishReplay(1)
            .refCount();
        this._canExecute = this.canRun
            .catch(ex => {
                this._exceptions.next(ex);
                return Observable.of(false);
            })
            .startWith(false)
            .combineLatest(this._isExecuting, (canRun, isExecuting) => {
                return canRun && !isExecuting;
            })
            .distinctUntilChanged()
            .publishReplay(1)
            .refCount();
        this._results = this._synchronizedExcecutionInfo
            .observeOn(scheduler)
            .filter(info => info.demarcation === ExecutionDemarcation.EndWithResult)
            .map(info => info.result);

        // Make sure that can execute is triggered to be a hot observable.
        this._canExecuteSubscription = this._canExecute.subscribe();
    }
 private _handle(observable: Observable<Response>, url: string, options?: RequestOptionsArgs): Observable<any> {
   return observable.catch((err: any): any => {
     console.log(err);
     if (err.status === 400 || err.status === 401 || err.status === 422) {
       console.log("Notifying...");
       console.log(err.json());
       this.growlMessageService.notifyError(err.json());
       return Observable.empty();
     }
     else {
       console.log("Redirecting...");
       this.router.navigate(['/error-page']);
       return Observable.empty();
     }
   })
     .retryWhen(error => error.delay(500))
     .timeout(2000, new Error('delay exceeded'))
     .finally(() => {
       this._afterCall(url, options);
     });
 }