【问题标题】:Angular2 Error Handling Best PracticeAngular2 错误处理最佳实践
【发布时间】:2017-11-26 21:10:04
【问题描述】:

我对 Angular2 错误处理的最佳实践有疑问。这是我用来捕获错误的代码:

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

我需要为每个新方法创建一个 Catch 还是可以一直使用 _errorHandler?

谢谢!

【问题讨论】:

  • 这实际上取决于您的功能优先级。例如:如果用户执行任何操作并且如果他得到错误,我们应该始终记录此用户错误。更多信息请看这里stackoverflow.com/a/44695829/5868331
  • @mayur 那么我应该总是在 de catch 方法中使用另一个函数吗?
  • 我认为没有必要嗯。做一个后端服务并记录错误只是为了跟踪。可以从我共享的 url stackoverflow.com/a/44695829/5868331 服务示例中检查日志记录和错误
  • @mayur 问题是我每 2 分钟发布一次。现在,当我遇到某个错误时,我想触发组件中的一个函数。所以我认为我需要为每个帖子制作一个不同的标签,这样他们就不能互相覆盖你怎么看?
  • 哦,是的,我认为您可以为此使用常见的错误处理程序,而不是让它变得更复杂..

标签: angular error-handling get


【解决方案1】:

服务中的捕获块和组件中的订阅错误回调

这是我在项目开发过程中开始使用的。服务中的 catch 块负责转换错误。组件中的错误回调负责更新任何视图逻辑。

服务

我很少从 api 以我需要的格式取回我需要的数据,所以我在 .map() 方法中转换数据。然后我将一个 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);
        }
}

现在我在发生错误时执行我想要的任何转换。例如,我可能会调用一个将错误转换为用户友好响应的全局方法

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

通过在服务中包含我的所有数据转换,我使视图逻辑保持良好和精简。我相信这种方法可以将各个部分分开。服务提供数据,组件更新视图。

【讨论】:

    【解决方案2】:

    仅在组件中捕获

    这就是我在项目中所做的,而且效果很好。服务永远不会有 catch 块。每个方法都返回一个流,所有参数都是流。将 catch 块放在组件内并采取适当的措施。

    例外情况

    有一些我在两者之间遇到的例外情况。

    • 获取身份验证令牌时出错,请处理该错误。重定向到登录页面。
    • 执行多个调用时出错,撤消更改

    我很少会处理介于两者之间的错误。大多数情况下,流在组件中开始和结束,并且错误处理在组件中完成。

    示例

    所有以$ 结尾的参数都是流。

    组件

    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>
    

    用户服务

    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 将有一个 catch 块,如果未找到 authtoken 或会话过期或任何原因,它将用户重定向到登录页面。将 catch 块位于组件中的所有错误都放置在所有位置。

    我只是想出了这个例子,如果有任何错误,请告诉我。

    【讨论】:

    • 你能举个例子吗?
    • @user3356007 你检查过这个例子吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 2014-11-28
    • 2019-10-28
    • 2011-03-26
    相关资源
    最近更新 更多