Angular2 Error Handling Best Practice

…衆ロ難τιáo~ 提交于 2019-12-06 07:59:27

问题


I have a question about the best practice of Angular2 error handling. The is the code i use to catch an error:

Getdata(data: object){

        let body = JSON.stringify(data);
        let headers = new Headers({ 'Content-Type': 'application/json' });

        return this.http.post('/getData', body)
            .map((res) => res.json())
            .catch(this._errorHandler);
    }

  _errorHandler(error: Response){
        console.log("Error Dataservice", error);
        return Observable.throw(error || "Server Error");
    }

Do i Need to make a Catch for each new method or can I always use the _errorHandler?

Thx!


回答1:


Catch only in Components

This is what I do in my project and it worked very well. Services never have catch block. Every method returns a stream and all params are streams. The catch block is put inside component and appropriate action is taken.

Exceptions

There are some exceptions where I catch in between .

  • Error while fetching auth token, handle the error. Redirect to login page.
  • Error while performing multiple calls, undo the changes

It is very rare I handle the errors in between. Most of the time the stream starts and ends in the component and error handling is done in the components.

Example

All params ending with $ are streams.

Component:

public error = false;
public errorMessage = '';
public users$; 

constructor(private router: Router, private _userService: UserService){
    const userId$ = this.router.params.map(params => params['id']);
    this.users$ = this._userService.getUsers$(userId$)
        .catch(error => {
           this.error = true;
           //translate error into user friendly language
           this.errorMessage = error;
        });
}

HTML

<ul *ngIf="!error"> 
 <li *ngFor="let user of users$ | async " >{{user.name}}</li>
</ul>

UserService

public getUsers$(userId$: Observable<string>): Observable<User[]>{
    return userId$.flatMap(
      userId => this.authService.getAuthToken$()
                    .flatMap(
                       authToken => this.http.get('url', {userId})
                                         .map(res => res.json())
   ); 
}

AuthService will have a catch block which redirects the user to login page if authtoken is not found or session expired or any reason. Rest all places for all errors the catch block is at the component.

I just came up with this example, if there are any errors let me know .




回答2:


Catch Blocks in Services & Subscription Error Callbacks in Components

This is what I have come to use as my project has developed. The catch block in the service is responsible for transforming the error. The error callback in the component is responsible for updating any view logic.

Service

I rarely get back the data I need in the format I need from the api, so I transform the data within a .map() method. Then I attach a catch block to the sequence.

// Service Class
getTableData(): Observable<Table>{
    return this.http.get('url')
        .map(res => {
            // transform data as needed
            return transformedData;
        }
        .catch(err => {
            // transform error as needed
            let transformedError = GlobalFunction.transformError(err);

            return Observable.throw(transformedError);
        }
}

now I perform whatever transform I want when an error occurs. For example, I may call a global method that converts an error into a user friendly response

// GlobalFunction Class
transformError(err){
   switch(err.status){
   case 404:
       return {
           status: err.status,
           message: 'Oops, it looks like that resource was not found'
       }
       break;
   }
}

Component

Now in my component, I subscribe to the sequence

// Component Class
ngOnInit(){
    this.loading = true;
    this.error = false;

    this.subscription = this.service.getTableData().subscribe(
        res => {
            this.table = res;
            this.loading = false;
        },
        err => {
            this.message = err.message;
            this.error = true;
            this.loading = false;
        }
     );
}

By containing all of my data transform in the service, I have kept the view logic nice & lean. I believe this approach keeps the pieces separate. The service provides the data & the component updates the view.



来源:https://stackoverflow.com/questions/44718862/angular2-error-handling-best-practice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!