溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Angular中處理錯(cuò)誤的方式是什么

發(fā)布時(shí)間:2021-06-29 11:08:26 來(lái)源:億速云 閱讀:125 作者:chen 欄目:web開(kāi)發(fā)

本篇內(nèi)容主要講解“Angular中處理錯(cuò)誤的方式是什么”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Angular中處理錯(cuò)誤的方式是什么”吧!

什么是Angular

Angualr 是一款來(lái)自谷歌的開(kāi)源的 web 前端框架,誕生于 2009 年,由 Misko Hevery 等人創(chuàng)建,后為 Google 所收購(gòu)。是一款優(yōu)秀的前端 JS 框架,已經(jīng)被用于 Google 的多款產(chǎn)品當(dāng)中。

AngularJS 是基于聲明式編程模式 是用戶可以基于業(yè)務(wù)邏輯進(jìn)行開(kāi)發(fā). 該框架基于HTML的內(nèi)容填充并做了雙向數(shù)據(jù)綁定從而完成了自動(dòng)數(shù)據(jù)同步機(jī)制. 最后, AngularJS 強(qiáng)化的DOM操作增強(qiáng)了可測(cè)試性.

try/catch

最熟悉的的方式,就是在代碼中添加try/catch塊,在try中發(fā)生錯(cuò)誤,就會(huì)被捕獲并且讓腳本繼續(xù)執(zhí)行。然而,隨著應(yīng)用程序規(guī)模的擴(kuò)大,這種方式將變得無(wú)法管理。

ErrorHandler

Angular提供了一個(gè)默認(rèn)的ErrorHandler,可以將錯(cuò)誤消息打印到控制臺(tái),因此可以攔截這個(gè)默認(rèn)行為來(lái)添加自定義的處理邏輯,下面嘗試編寫錯(cuò)誤處理類:

import { ErrorHandler, Injectable } from "@angular/core";
import { HttpErrorResponse } from "@angular/common/http";

@Injectable()
export class ErrorsHandler implements ErrorHandler {
  handleError(error: Error | HttpErrorResponse) {
    if (!navigator.onLine) {
      console.error("Browser Offline!");
    } else {
      if (error instanceof HttpErrorResponse) {
        if (!navigator.onLine) {
          console.error("Browser Offline!");
        } else {
          // Handle Http Error (4xx, 5xx, ect.)
          console.error("Http Error!");
        }
      } else {
        // Handle Client Error (Angular Error, ReferenceError...)
        console.error("Client Error!");
      }
      console.error(error);
    }
  }
}

通常在app下創(chuàng)建一個(gè)共享目錄shared,并將此文件放在providers文件夾中

現(xiàn)在,需要更改應(yīng)用程序的默認(rèn)行為,以使用我們自定義的類而不是ErrorHandler。修改app.module.ts文件,從@angular/core導(dǎo)入ErrorHandler,并將providers添加到@NgModule模塊,代碼如下:

import { NgModule, ErrorHandler } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";

// Providers
import { ErrorsHandler } from "./shared/providers/error-handler";

import { AppComponent } from "./app.component";

@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [AppComponent],
  providers: [{ provide: ErrorHandler, useClass: ErrorsHandler }],
  bootstrap: [AppComponent]
})
export class AppModule {}

HttpInterceptor

HttpInterceptor提供了一種攔截HTTP請(qǐng)求/響應(yīng)的方法,就可以在傳遞它們之前處理。例如,可以在拋出錯(cuò)誤之前重試幾次HTTP請(qǐng)求。這樣,就可以優(yōu)雅地處理超時(shí),而不必拋出錯(cuò)誤。

還可以在拋出錯(cuò)誤之前檢查錯(cuò)誤的狀態(tài),使用攔截器,可以檢查401狀態(tài)錯(cuò)誤碼,將用戶重定向到登錄頁(yè)面。

import { Injectable } from "@angular/core";
import { HttpEvent, HttpRequest, HttpHandler, HttpInterceptor, HttpErrorResponse } from "@angular/common/http";
import { Observable, throwError } from "rxjs";
import { retry, catchError } from "rxjs/operators";

@Injectable()
export class HttpsInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      retry(1),
      catchError((error: HttpErrorResponse) => {
        if (error.status === 401) {
          // 跳轉(zhuǎn)到登錄頁(yè)面
        } else {
          return throwError(error);
        }
      })
    );
  }
}

同樣需要添加到app.module.ts

import { NgModule, ErrorHandler } from "@angular/core";
import { HTTP_INTERCEPTORS } from "@angular/common/http";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";

// Providers
import { ErrorsHandler } from "./shared/providers/error-handler";
import { HttpsInterceptor } from "./shared/providers/http-interceptor";

import { AppComponent } from "./app.component";

@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [AppComponent],
  providers: [
    { provide: ErrorHandler, useClass: ErrorsHandler },
    { provide: HTTP_INTERCEPTORS, useClass: HttpsInterceptor, multi: true }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

多提供者用于創(chuàng)建可擴(kuò)展服務(wù),其中系統(tǒng)帶有一些默認(rèn)提供者,也可以注冊(cè)其他提供者。默認(rèn)提供程序和其他提供程序的組合將用于驅(qū)動(dòng)系統(tǒng)的行為。

Notifications

在控制臺(tái)打印錯(cuò)誤日志對(duì)于開(kāi)發(fā)者來(lái)說(shuō)非常友好,但是對(duì)于用戶來(lái)說(shuō)則需要一種更加友好的方式來(lái)告訴這些錯(cuò)誤何時(shí)從GUI中發(fā)生。根據(jù)錯(cuò)誤類型,推薦兩個(gè)組件:SnackbarDialog

  • Snackbar:推薦用于簡(jiǎn)單的提示,比如表單缺少必填字段或通知用戶可預(yù)見(jiàn)的錯(cuò)誤(無(wú)效電子郵件、用戶名太長(zhǎng)等)。

  • Dialog:當(dāng)存在未知的服務(wù)器端或客戶端錯(cuò)誤時(shí),推薦使用這種方式;通過(guò)這種方式,可以顯示更多的描述,甚至call-to-action,比如允許用戶輸入他們的電子郵件來(lái)跟蹤錯(cuò)誤。

shared文件夾中添加一個(gè)服務(wù)來(lái)處理所有通知,新建services文件夾,創(chuàng)建文件:notification.service.ts,代碼如下:

import { Injectable } from "@angular/core";
import { MatSnackBar } from "@angular/material/snack-bar";

@Injectable({
  providedIn: "root"
})
export class NotificationService {
  constructor(public snackBar: MatSnackBar) {}

  showError(message: string) {
    this.snackBar.open(message, "Close", { panelClass: ["error"] });
  }
}

更新error-handler.ts,添加NotificationService

import { ErrorHandler, Injectable, Injector } from "@angular/core";
import { HttpErrorResponse } from "@angular/common/http";
// Services
import { NotificationService } from "../services/notification.service";

@Injectable()
export class ErrorsHandler implements ErrorHandler {
  //Error handling需要先加載,使用Injector手動(dòng)注入服務(wù)
  constructor(private injector: Injector) {}
  handleError(error: Error | HttpErrorResponse) {
    const notifier = this.injector.get(NotificationService);
    if (!navigator.onLine) {
      //console.error("Browser Offline!");
      notifier.showError("Browser Offline!");
    } else {
      if (error instanceof HttpErrorResponse) {
        if (!navigator.onLine) {
          //console.error("Browser Offline!");
          notifier.showError(error.message);
        } else {
          // Handle Http Error (4xx, 5xx, ect.)
          // console.error("Http Error!");
          notifier.showError("Http Error: " + error.message);
        }
      } else {
        // Handle Client Error (Angular Error, ReferenceError...)
        // console.error("Client Error!");
        notifier.showError(error.message);
      }
      console.error(error);
    }
  }
}

如果在一個(gè)組件中拋出一個(gè)錯(cuò)誤,可以看到一個(gè)很好的snackbar消息:

日志和錯(cuò)誤跟蹤

當(dāng)然不能期望用戶向報(bào)告每個(gè)bug,一旦部署到生產(chǎn)環(huán)境中,就不能看到任何控制臺(tái)日志。因此就需要能夠記錄錯(cuò)誤的后端服務(wù)與自定義邏輯寫入數(shù)據(jù)庫(kù)或使用現(xiàn)有的解決方案,如Rollbar、Sentry、Bugsnag。

接下來(lái)創(chuàng)建一個(gè)簡(jiǎn)單的錯(cuò)誤跟蹤服務(wù),創(chuàng)建logging.service.ts

import { Injectable } from "@angular/core";
import { HttpErrorResponse } from "@angular/common/http";

@Injectable({
  providedIn: "root"
})
export class LoggingService {
  constructor() {}

  logError(error: Error | HttpErrorResponse) {
    // This will be replaced with logging to either Rollbar, Sentry, Bugsnag, ect.
    if (error instanceof HttpErrorResponse) {
      console.error(error);
    } else {
      console.error(error);
    }
  }
}

將服務(wù)添加到error-handler.ts中:

import { ErrorHandler, Injectable, Injector } from "@angular/core";
import { HttpErrorResponse } from "@angular/common/http";
// Services
import { NotificationService } from "../services/notification.service";
import { LoggingService } from "../services/logging.service";

@Injectable()
export class ErrorsHandler implements ErrorHandler {
  //Error handling需要先加載,使用Injector手動(dòng)注入服務(wù)
  constructor(private injector: Injector) {}
  handleError(error: Error | HttpErrorResponse) {
    const notifier = this.injector.get(NotificationService);
    const logger = this.injector.get(LoggingService);
    if (!navigator.onLine) {
      //console.error("Browser Offline!");
      notifier.showError("Browser Offline!");
    } else {
      if (error instanceof HttpErrorResponse) {
        if (!navigator.onLine) {
          //console.error("Browser Offline!");
          notifier.showError(error.message);
        } else {
          // Handle Http Error (4xx, 5xx, ect.)
          // console.error("Http Error!");
          notifier.showError("Http Error: " + error.message);
        }
      } else {
        // Handle Client Error (Angular Error, ReferenceError...)
        // console.error("Client Error!");
        notifier.showError(error.message);
      }
      // console.error(error);
      logger.logError(error);
    }
  }
}

到此,相信大家對(duì)“Angular中處理錯(cuò)誤的方式是什么”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI