使用 Angular HttpClient 服务处理异常

发布日期:2026-07-08 08:56:04   来源 : 杭州电子商务研究院    浏览量 :15
杭州电子商务研究院 发布日期:2026-07-08 08:56:04  
15

介绍

HTTP 请求极易出错,因为它们周围通常有很多未知因素。您尝试访问的服务器是否正常运行?API 是否返回了您期望的有效负载?在本指南中,您将了解当这些问题没有得到适当回答时该怎么办。我们将讨论在使用 Angular 的 HttpClient 服务时管理应用内 HTTP 异常的一些最佳方法。

开始处理 HTTP 异常

当谈到在 Angular 中处理 HTTP 异常时,几乎不可能不谈论 RxJs。Angular 框架大量采用了 RxJs 库 - 该库将响应式编程引入了 JavaScript 生态系统。Angular 自己的 HttpClient 在底层使用了 RxJs 来确保客户端具有可观察的 API。

为了正确处理异常,您需要熟悉一些 RxJs 运算符。本指南中我们将关注的主要运算符是 catchErrorthrowError运算符。

捕获 HTTP 异常

使用catchError运算符可以捕获可观察流中可能发生的错误。让我们看看如何在示例应用中使用此运算符。

以下是从服务器获取书籍的示例服务。它看起来像这样:

      import { HttpClient } from '@angular/common/http';
    import { Injectable } from '@angular/core';
    import { Book } from 'app/models/book';

    @Injectable()
    export class BooksService {
        private booksApiUrl = '/api/books';

        constructor(private http: HttpClient) { }

        getBooks(): Observable<Book[]> {
            return this.http.get(this.booksApiUrl);
        }
    }
    

下面是一个使用BooksService的示例组件:

      import { Component } from '@angular/core';
import { BooksService } from 'app/services/books';
import { Book } from 'app/models/book';

@Component({
  selector: 'app-books',
  template: `
    <ul *ngFor="let book of books$">
        <li>{{ book.title }}</li>
    </ul>
    `
})
export class BooksComponent {
    books$: Observable<Book[]>;

    constructor(private booksService: BooksService) {
        this.books$ = this.booksService.getBooks();
    }
}
    

上面,BooksComponent与BooksService通信,以便从服务器获取书籍负载。​​如果在此请求期间出现问题怎么办?当然,您需要以某种方式处理此异常。

接下来,将catchError操作符添加到BooksComponent来处理异常:

      import { Component } from '@angular/core';
import { BooksService } from 'app/services/books';
import { Book } from 'app/models/book';
import { catchError } from 'rxjs/operators';
import { of } from 'rxjs';

@Component({
  selector: 'app-books',
  template: `
    <error-alert *ngIf="errorMsg" [msg]="errorMsg"></error-alert>
    <ul *ngFor="let book of books$">
        <li>{{ book.title }}</li>
    </ul>
    `
})
export class BooksComponent {
    books$: Observable<Book[]>;
    errorMsg: string;

    constructor(private booksService: BooksService) {
        this.books$ =
            this.booksService
                .getBooks()
                .pipe(
                    catchError(error => {
                        if (error.error instanceof ErrorEvent) {
                            this.errorMsg = `Error: ${error.error.message}`;
                        } else {
                            this.errorMsg = `Error: ${error.message}`;
                        }
                        return of([]);
                    })
                );
    }
}
    

您已修改BooksComponent以捕获 HTTP 请求中可能发生的任何异常!您还使用了可观察对象辅助函数来确保当发生错误时,可观察对象返回一个空数组。现在,当发生错误时,用户可以轻松看到消息。

但是,如果你想对显示的错误消息进行更多的自定义控制,该怎么办?在下一节中,你将学习如何使用throwError运算符来实现这一点。

重新抛出 HTTP 异常

很可能,当发生异常时,您不想向用户显示从 Angular HttpClient 获得的确切错误消息。自定义此消息的一个好方法是使用throwError抛出您自己的自定义异常。首先,更新您的BooksService以根据 HTTP 请求的最终状态抛出自定义错误。

      import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Book } from 'app/models/book';
import { catchError, throwError } from 'rxjs/operators';

@Injectable()
export class BooksService {
    private booksApiUrl = '/api/books';

    constructor(private http: HttpClient) { }

    getBooks(): Observable<Book[]> {
        return this.http
                .get(this.booksApiUrl)
                .pipe(
                    catchError(error => {
                        let errorMsg: string;
                        if (error.error instanceof ErrorEvent) {
                            this.errorMsg = `Error: ${error.error.message}`;
                        } else {
                            this.errorMsg = this.getServerErrorMessage(error);
                        }

                        return throwError(errorMsg);
                    })
                );
    }

    private getServerErrorMessage(error: HttpErrorResponse): string {
        switch (error.status) {
            case 404: {
                return `Not Found: ${error.message}`;
            }
            case 403: {
                return `Access Denied: ${error.message}`;
            }
            case 500: {
                return `Internal Server Error: ${error.message}`;
            }
            default: {
                return `Unknown Server Error: ${error.message}`;
            }

        }
    }
}
    

上述代码将一些错误处理逻辑从BooksComponent移至服务。通过使用throwError运算符和新的getServerErrorMessage方法,您现在可以从服务中抛出自定义错误来处理 HTTP 错误。

现在,简化你的BooksComponent

      import { Component } from '@angular/core';
import { BooksService } from 'app/services/books';
import { Book } from 'app/models/book';
import { catchError } from 'rxjs/operators';
import { of } from 'rxjs';

@Component({
  selector: 'app-books',
  template: `
    <error-alert *ngIf="errorMsg" [msg]="errorMsg"></error-alert>
    <ul *ngFor="let book of books$">
        <li>{{ book.title }}</li>
    </ul>
    `
})
export class BooksComponent {
    books$: Observable<Book[]>;
    errorMsg: string;

    constructor(private booksService: BooksService) {
        this.books$ =
            this.booksService
                .getBooks()
                .pipe(
                    catchError(error => {
                        this.errorMsg = error.message;
                        return of([]);
                    })
                );
    }

}
    

最佳实践是让组件尽可能简单。在本例中,您能够适当地将错误处理逻辑从BooksComponent移至BooksService

结论

在本指南中,您学习了如何管理应用中的 HTTP 异常。您已经了解了如何使用 RxJs catchError运算符来捕获使用 Angular HttpClientservice 时发生的任何 HTTP 异常。您还了解了如何使用 RxJs throwError运算符有意抛出自己的错误或重新抛出捕获的错误。通过使用这两种技术,您可以很好地处理任何 HTTP 驱动的应用程序中出现的意外错误。

了解更多

探索 Pluralsight 的这些 Angular 和 HTTP 课程以继续学习:

以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据