จัดการ HTTP Error ใน Angular

Oct. 26, 2024 · boychawin

ถ้ามี error เกิดขึ้นในระบบ เราสามารถใช้ Interceptor เพื่อจัดการได้อย่างรวดเร็วและเป็นระเบียบ และนี่คือเหตุผลหลัก ๆ ที่ควรใช้ Interceptor ในการจัดการข้อผิดพลาด

  • จัดการ Error ในที่เดียว ทำให้โค้ดสะอาดขึ้น
  • ปรับแต่ง Error Message ให้เป็นรูปแบบที่ต้องการ

โค้ดตัวอย่างสำหรับจัดการ Error ด้วย HttpErrorInterceptor

โค้ดชุดนี้จะสร้าง HttpErrorInterceptor เพื่อจัดการกับ error ที่เกิดขึ้นเมื่อเราเรียก API แล้วเกิดปัญหา โดยจะแปลงข้อมูล error ให้เป็นรูปแบบเฉพาะที่เรากำหนด เพื่อให้ง่ายต่อการแสดงผลหรือจัดการเพิ่มเติม

  1. สร้าง Interface และ Class เพื่อกำหนดโครงสร้าง Error

เรากำหนด IErrorStandard เป็น interface สำหรับเก็บรายละเอียด error และสร้าง ErrorStandard เพื่อใช้งานข้อมูล error ได้อย่างเป็นระบบ

export interface IErrorStandard {
  resultCode: string;
  resultDescription: string;
  developerMessage: string;
}

export class ErrorStandard {
  resultCode = '';
  resultDescription = '';
  developerMessage = '';

  constructor(error?: Partial<IErrorStandard>) {
    ObjectUtil.assignByTarget(this, error);
  }
}
  1. Utility Class: ตัวช่วยในการจัดการกับ Object

ObjectUtil เป็น utility ที่จะช่วยให้เราสามารถจัดการข้อมูลภายใน object ได้สะดวก เช่น การคัดลอกข้อมูลจากแหล่งหนึ่งไปยังอีกแหล่งอย่างละเอียด หรือการแทนที่ค่าภายใน object ด้วยค่า null

export class ObjectUtil {
  static assignByTarget(target: any, source: any) {
    for (const [key, value] of Object.entries(target)) {
      if (
        typeof value === 'object' &&
        value !== null &&
        typeof source === 'object' &&
        source.hasOwnProperty(key)
      ) {
        ObjectUtil.assignByTarget(value, source[key]);
      } else if (typeof source === 'object' && source && key in source) {
        target[key] = source[key] !== undefined ? source[key] : value;
      }
    }
  }

}
  1. สร้าง HttpErrorInterceptor สำหรับจัดการ HTTP Error

ใน HttpErrorInterceptor นี้ เราจะเช็คว่าเมื่อเกิด error ขึ้น ระบบจะตรวจสอบประเภท error แล้วแปลงข้อมูลไปยัง ErrorStandard และโยน error นี้กลับเพื่อให้จัดการใน component ที่เรียกใช้งาน

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

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
  intercept(
    request: HttpRequest<unknown>,
    next: HttpHandler,
  ): Observable<HttpEvent<unknown>> {

    return next.handle(request).pipe(
      catchError((errorResponse: HttpErrorResponse) => {
        if (typeof errorResponse.error === 'string') {
          throw new ErrorStandard({ developerMessage: errorResponse.error });
        }
        throw new ErrorStandard(errorResponse.error);
      }),
    );
  }
}
  1. ตั้งค่า Interceptor ในโมดูลหลัก

จากนั้นให้นำ HttpErrorInterceptor เข้าไปกำหนดไว้ในโมดูลหลักเพื่อให้ Interceptor นี้ทำงานตลอดทั้งแอปพลิเคชัน


import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { HttpErrorInterceptor } from './http-error.interceptor';

@NgModule({
  imports: [
    HttpClientModule,
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: HttpErrorInterceptor,
      multi: true,
    },
  ],
})
export class AppModule { }
  1. ทดสอบ Error Handling ใน Component

เพื่อทดสอบ เราจะเรียก API ที่ไม่ถูกต้อง และให้ HttpErrorInterceptor จัดการ error ก่อนโยนกลับมายัง component เพื่อแสดงข้อมูล error ที่ถูกแปลงแล้วในรูปแบบ ErrorStandard


import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-example',
  template: `<button (click)="makeRequest()">Make Request</button>`,
})
export class ExampleComponent implements OnInit {
  constructor(private http: HttpClient) {}

  ngOnInit(): void {
    this.makeRequest()
  }

  makeRequest() {
    this.http.get('https://jsonplaceholder.typicode.com/invalid-url')
      .subscribe({
        next: (data) => console.log(data),
        error: (err) => console.log('Error caught in component:', err),
      });
  }
}

เมื่อเรียกใช้งาน API นี้ เราจะเห็นว่ามี error ขึ้นและถูกจัดการตามที่กำหนดใน HttpErrorInterceptor โดยข้อมูล error ถูกแปลงเป็น ErrorStandard และแสดงใน console

สรุป

การใช้ HttpErrorInterceptor ใน Angular ช่วยให้การจัดการ error เป็นระบบมากขึ้น ไม่ว่าจะเป็นการจับ error ทั้งฝั่งเซิร์ฟเวอร์และฝั่งไคลเอนต์ พร้อมปรับแต่งการแสดงผลได้ตามต้องการ