简体   繁体   English

如何手动抛出可观察到的错误?

[英]How to throw an observable error manually?

I am working on an Angular app in which I am making a rest call through HTTP as below:我正在开发一个 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;
        }
    });
}

Basically I want my component to get response & error in my subscribe call, ie基本上我希望我的组件在我的订阅调用中得到响应和错误,即

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;     
  }
);

but my API always returns success as it is defined that way.但我的 API 总是返回成功,因为它是这样定义的。

How can I throw an error message if response.success == 0 , so that it will be accessed inside error argument of my subscribe callback?如果response.success == 0 ,我如何抛出错误消息,以便在我的订阅回调的错误参数中访问它?

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

Edit for rxjs 6 :rxjs 6编辑:

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

rxjs 6 rxjs 6

import { throwError } from 'rxjs';

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

rxjs 5 rxjs 5

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

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

What you return with ErrorObservable is up to you你用ErrorObservable返回什么取决于你

with rxjs 6使用 rxjs 6

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

rxjs 5 rxjs 5

Either任何一个

throw response;

or或者

throw Observable.throw(response);

Here is the official example (that emits number 7 and then error 'oops!'):这是官方示例(发出数字 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));

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

Use the catch operator使用捕获运算符

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()
   );

And handle the error like this:并像这样处理错误:

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

Most of my issues were related to the imports, so here's the code that worked for me...我的大部分问题都与导入有关,所以这是对我有用的代码......

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) {
...
        }
    });
}

This will be the solution if you are facing errors like...如果您遇到以下错误,这将是解决方案...

ERROR TypeError: WEBPACK_IMPORTED_MODULE_2_rxjs_Observable .Observable.throw is not a function错误类型错误: WEBPACK_IMPORTED_MODULE_2_rxjs_Observable .Observable.throw不是函数

Usually when you're throwing an error you'll be doing so at the exact moment the problem occurred and you want to raise it immediately, but this may not always be the case.通常,当您抛出错误时,您会在问题发生的确切时刻这样做,并且您想立即提出它,但情况可能并非总是如此。

For instance there is the timeoutWith() operator, which is perhaps one of the most likely reasons you'll need to do this.例如,有timeoutWith()运算符,这可能是您需要执行此操作的最可能原因之一。

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

This takes an 'error factory', which is a function.这需要一个“错误工厂”,这是一个函数。

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

eg.例如。

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

Note that when using timeoutWith you'll never get the actual server response back - so if the server gave a specific error you'd never see it.请注意,当使用timeoutWith您永远不会得到实际的服务器响应 - 因此,如果服务器给出特定错误,您将永远不会看到它。 This above example can be very useful in debugging, but be sure not to display the error to the end user if you use the above example.上面的示例在调试中非常有用,但如果使用上面的示例,请确保不要向最终用户显示错误。

AN error factory is helpful because it doesn't evaluate the code until the actual error occurs.错误工厂很有用,因为它在实际错误发生之前不会评估代码。 So you can put 'expensive' or debugging operations inside that will get executed when the error is actually finally needed.因此,您可以将“昂贵的”或调试操作放入其中,当实际最终需要错误时将执行这些操作。

If you need to use a 'factory' to create your error somewhere other than in timeout you can use the following.如果您需要使用“工厂”在超时以外的其他地方创建错误,您可以使用以下内容。

 EMPTY.pipe(throwIfEmpty(errorFactory)) 

rxjs 7 rxjs 7

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

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

You can use catchError(error) => console.log(error) inside a pipe您可以在 pipe 中使用 catchError(error) => console.log(error)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM