简体   繁体   English

Angular2错误处理最佳实践

[英]Angular2 Error Handling Best Practice

I have a question about the best practice of Angular2 error handling. 我有一个关于Angular2错误处理的最佳实践的问题。 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? 我是否需要为每个新方法创建一个Catch,或者我是否可以始终使用_errorHandler?

Thx! 谢谢!

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. 服务中的catch块负责转换错误。 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. 我很少从api中以我需要的格式获取所需的数据,因此我在.map()方法中转换数据。 Then I attach a catch block to the sequence. 然后我将一个catch块附加到序列中。

// 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. 该服务提供数据和组件更新视图。

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. catch块放在组件内部并采取适当的操作。

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 HTML

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

UserService 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. 如果未找到authtoken或会话过期或任何原因,AuthService将具有一个catch块,用于将用户重定向到登录页面。 Rest all places for all errors the catch block is at the component. 将所有错误放在所有位置,以便catch块位于组件中。

I just came up with this example, if there are any errors let me know . 我刚刚想出了这个例子,如果有任何错误让我知道。

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

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