如何处理解析器中的错误

马特M:

我正在尝试使用解析器以制作更好的UX。一切顺利,一切顺利。我似乎无法弄清楚的是如何处理异常。我的解析器调用了一个服务,该服务命中了一个webapi项目。一个例子:

FooResolver:

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Foo> {
      return this.fooService.getById(route.params['id']).catch(err => {
    ****not sure what to do/return in the case of a server error****
    return Observable.throw(err);
  });
} 

FooService:

  public getById(id: string): Observable<Foo> {
    return this.http.get(`${ this.apiUrl }/${ id }`)
        .map(this.extractData)
        .catch(this.handleError);
}

handleError函数:

   protected handleError (error: Response | any) {
    // Todo: Log the error   
    // Errors will be handled uniquely by the component that triggered them
    return Observable.throw(error);
}

在FooComponent内,我这样做(如果从服务/解析器返回错误,则永远不会发生):

FooComponent

ngOnInit(): void {
    this.foo= this.route.snapshot.data['foo'];
    if (this.foo) {
       this.createForm(this.foo);
    }
}

我尝试抛出错误(如图所示)-我在控制台中收到此异常:

未捕获(承诺):状态响应:500内部服务器URL错误:

然后返回new Observable<Foo>(),得到:

无法读取未定义的属性“订阅”

我有几个解析器,所有解析器都可以在服务器上遇到异常,但是我不知道如果发生这些异常该怎么办。

DeborahK:

这是我使用Gunter建议的技术的一个带有错误处理的解析器的示例:

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/of';

import { IProduct } from './product';
import { ProductService } from './product.service';

@Injectable()
export class ProductResolver implements Resolve<IProduct> {

    constructor(private productService: ProductService,
                private router: Router) { }

    resolve(route: ActivatedRouteSnapshot,
            state: RouterStateSnapshot): Observable<IProduct> {
        let id = route.params['id'];
        if (isNaN(+id)) {
            console.log(`Product id was not a number: ${id}`);
            this.router.navigate(['/products']);
            return Observable.of(null);
        }
        return this.productService.getProduct(+id)
            .map(product => {
                if (product) {
                    return product;
                }
                console.log(`Product was not found: ${id}`);
                this.router.navigate(['/products']);
                return null;
            })
            .catch(error => {
                console.log(`Retrieval error: ${error}`);
                this.router.navigate(['/products']);
                return Observable.of(null);
            });
    }
}

您可以在此处找到完整的示例:APM-final文件夹中的https://github.com/DeborahK/Angular-Routing

更新2019年2月

对于解析程序中的错误处理,这是一个更好的答案:

1)将您的界面包装在另一个具有可选错误属性的界面中:

/* Defines the product entity */
export interface Product {
  id: number;
  productName: string;
  productCode: string;
  category: string;
  tags?: string[];
  releaseDate: string;
  price: number;
  description: string;
  starRating: number;
  imageUrl: string;
}

export interface ProductResolved {
  product: Product;
  error?: any;
}

2)解析到该界面:

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

import { ProductResolved } from './product';
import { ProductService } from './product.service';

@Injectable({
  providedIn: 'root'
})
export class ProductResolver implements Resolve<ProductResolved> {

  constructor(private productService: ProductService) { }

  resolve(route: ActivatedRouteSnapshot,
          state: RouterStateSnapshot): Observable<ProductResolved> {
    const id = route.paramMap.get('id');
    if (isNaN(+id)) {
      const message = `Product id was not a number: ${id}`;
      console.error(message);
      return of({ product: null, error: message });
    }

    return this.productService.getProduct(+id)
      .pipe(
        map(product => ({ product: product })),
        catchError(error => {
          const message = `Retrieval error: ${error}`;
          console.error(message);
          return of({ product: null, error: message });
        })
      );
  }

}

3)在组件中,拉出您需要的一部分接口:

  ngOnInit(): void {
    const resolvedData: ProductResolved =
      this.route.snapshot.data['resolvedData'];
    this.errorMessage = resolvedData.error;
    this.product = resolvedData.product;
  }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章