• 技术文章 >web前端 >js教程

    一文了解Angular中处理错误的方式

    青灯夜游青灯夜游2021-06-29 10:52:05转载257
    Angular中可以如何处理错误?本篇文章带大家了解一下Angular中的错误处理的机制,介绍处理错误的方式。

    错误处理是编写代码经常遇见的并且必须处理的需求,很多时候处理异常的逻辑是为了避免程序的崩溃,下面来一起看看Angular处理错误的方式。【相关教程推荐:《angular教程》】

    什么是Angular

    Angualr 是一款来自谷歌的开源的 web 前端框架,诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。

    AngularJS 是基于声明式编程模式 是用户可以基于业务逻辑进行开发. 该框架基于HTML的内容填充并做了双向数据绑定从而完成了自动数据同步机制. 最后, AngularJS 强化的DOM操作增强了可测试性.

    try/catch

    最熟悉的的方式,就是在代码中添加try/catch块,在try中发生错误,就会被捕获并且让脚本继续执行。然而,随着应用程序规模的扩大,这种方式将变得无法管理。

    ErrorHandler

    Angular提供了一个默认的ErrorHandler,可以将错误消息打印到控制台,因此可以拦截这个默认行为来添加自定义的处理逻辑,下面尝试编写错误处理类:

    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下创建一个共享目录shared,并将此文件放在providers文件夹中

    现在,需要更改应用程序的默认行为,以使用我们自定义的类而不是ErrorHandler。修改app.module.ts文件,从@angular/core导入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请求/响应的方法,就可以在传递它们之前处理。例如,可以在抛出错误之前重试几次HTTP请求。这样,就可以优雅地处理超时,而不必抛出错误。

    还可以在抛出错误之前检查错误的状态,使用拦截器,可以检查401状态错误码,将用户重定向到登录页面。

    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) {
              // 跳转到登录页面
            } 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 {}

    多提供者用于创建可扩展服务,其中系统带有一些默认提供者,也可以注册其他提供者。默认提供程序和其他提供程序的组合将用于驱动系统的行为。

    Notifications

    在控制台打印错误日志对于开发者来说非常友好,但是对于用户来说则需要一种更加友好的方式来告诉这些错误何时从GUI中发生。根据错误类型,推荐两个组件:SnackbarDialog

    shared文件夹中添加一个服务来处理所有通知,新建services文件夹,创建文件: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手动注入服务
      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);
        }
      }
    }

    如果在一个组件中抛出一个错误,可以看到一个很好的snackbar消息:

    日志和错误跟踪

    当然不能期望用户向报告每个bug,一旦部署到生产环境中,就不能看到任何控制台日志。因此就需要能够记录错误的后端服务与自定义逻辑写入数据库或使用现有的解决方案,如RollbarSentryBugsnag

    接下来创建一个简单的错误跟踪服务,创建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);
        }
      }
    }

    将服务添加到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手动注入服务
      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);
        }
      }
    }

    至此,整个错误处理的机制已经介绍完了,基本上跟其他框架或者语言开发的项目处理方式类似。

    更多编程相关知识,请访问:编程入门!!

    以上就是一文了解Angular中处理错误的方式的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除
    专题推荐:Angular 错误处理
    上一篇:Node版本管理工具--nvm-windows的使用方法(windows环境) 下一篇:简单对比,看看TypeScript中interface和type间的区别
    大前端线上培训班

    相关文章推荐

    • 浅谈Angular中父子组件间怎么传递数据• 浅谈Angular中组件的生命周期• 聊聊Angular中的指令(Directive)• 浅谈Angular中的模块(NgModule),延迟加载模块• 聊一聊Angular中的路由(Routing)• 浅谈angular中优化绑定(脏检查)性能的小技巧

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网