簡體   English   中英

如何手動拋出可觀察到的錯誤?

[英]How to throw an observable error manually?

我正在開發一個 Angular 應用程序,我正在通過 HTTP 撥打 rest 電話,如下所示:

login(email, password) {
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    let options = new RequestOptions({ headers: headers });
    let body = `identity=${email}&password=${password}`;
    return this.http.post(`${this._configService.getBaseUrl()}/login`, body, options)
    .map((res: any) => {
        let response: any = JSON.parse(res._body);
        if (response.success == 0) {
          Observable.throw(response);  // not working
        } else if (response.success == 1) {
          console.log('success');
          localStorage.setItem('auth_token', 'authenticated');
          this.loggedIn = true;
          return response;
        }
    });
}

基本上我希望我的組件在我的訂閱調用中得到響應和錯誤,即

this._authenticateService.login(this.loginObj['identity'],this.loginObj['password']).subscribe(
  (success)=>{      
    this.credentialsError=null;  
    this.loginObj={};  
    this._router.navigate(['dashboard']);    
  },
  (error)=>{
    console.log(error);        
    this.credentialsError=error;     
  }
);

但我的 API 總是返回成功,因為它是這樣定義的。

如果response.success == 0 ,我如何拋出錯誤消息,以便在我的訂閱回調的錯誤參數中訪問它?

if (response.success == 0) {
   throw Observable.throw(response);  
 } 

rxjs 6編輯:

if (response.success == 0) {
   throw throwError(response);  
 } 

rxjs 6

import { throwError } from 'rxjs';

if (response.success == 0) {
  return throwError(response);  
}

rxjs 5

import { ErrorObservable } from 'rxjs/observable/ErrorObservable';

if (response.success == 0) {
  return new ErrorObservable(response);  
}

你用ErrorObservable返回什么取決於你

使用 rxjs 6

import { throwError } from 'rxjs';
throwError('hello');

rxjs 5

任何一個

throw response;

或者

throw Observable.throw(response);

這是官方示例(發出數字 7,然后錯誤“哎呀!”):

import { throwError, concat, of } from 'rxjs';

const result = concat(of(7), throwError(new Error('oops!')));
result.subscribe(x => console.log(x), e => console.error(e));

來自: https : //rxjs-dev.firebaseapp.com/api/index/function/throwError

使用捕獲運算符

this.calcSub = this.http.post(this.constants.userUrl + "UpdateCalculation", body, { headers: headers })
   .map((response: Response) => {
      var result = <DataResponseObject>response.json();
         return result;
   })
   .catch(this.handleError)
   .subscribe(
      dro => this.dro = dro,
      () => this.completeAddCalculation()
   );

並像這樣處理錯誤:

private handleError(error: Response) {
    console.error(error); // log to console instead
    return Observable.throw(error.json().error || 'Server Error');
}

我的大部分問題都與導入有關,所以這是對我有用的代碼......

import {_throw} from 'rxjs/observable/throw';
login(email, password) {
...
    return this.http.post(`${this._configService.getBaseUrl()}/login`, body, options)
    .map((res: any) => {
...
        if (response.success == 0) {
           _throw(response);  
        } else if (response.success == 1) {
...
        }
    });
}

如果您遇到以下錯誤,這將是解決方案...

錯誤類型錯誤: WEBPACK_IMPORTED_MODULE_2_rxjs_Observable .Observable.throw不是函數

通常,當您拋出錯誤時,您會在問題發生的確切時刻這樣做,並且您想立即提出它,但情況可能並非總是如此。

例如,有timeoutWith()運算符,這可能是您需要執行此操作的最可能原因之一。

results$ = server.getResults().pipe(timeoutWith(10000, ....) )

這需要一個“錯誤工廠”,這是一個函數。

 errorFactory = () => 'Your error occurred at exactly ' + new Date()

例如。

results$ = server.searchCustomers(searchCriteria).pipe(timeoutWith(10000, 
              () => 'Sorry took too long for search ' + JSON.stringify(searchCriteria)) )

請注意,當使用timeoutWith您永遠不會得到實際的服務器響應 - 因此,如果服務器給出特定錯誤,您將永遠不會看到它。 上面的示例在調試中非常有用,但如果使用上面的示例,請確保不要向最終用戶顯示錯誤。

錯誤工廠很有用,因為它在實際錯誤發生之前不會評估代碼。 因此,您可以將“昂貴的”或調試操作放入其中,當實際最終需要錯誤時將執行這些操作。

如果您需要使用“工廠”在超時以外的其他地方創建錯誤,您可以使用以下內容。

 EMPTY.pipe(throwIfEmpty(errorFactory)) 

rxjs 7

throwError(() => new Error(response))

更多信息https://rxjs.dev/deprecations/break-changes#throwerror

您可以在 pipe 中使用 catchError(error) => console.log(error)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM