Kỹ thuật xử lý lỗi nâng cao trong TypeScript

Xử lý lỗi hiệu quả là rất quan trọng để xây dựng các ứng dụng TypeScript mạnh mẽ. Ngoài các khối try-catch cơ bản, TypeScript cung cấp một số kỹ thuật nâng cao để xử lý lỗi một cách khéo léo và đảm bảo độ tin cậy của mã. Bài viết này khám phá một số chiến lược xử lý lỗi nâng cao này.

1. Các lớp lỗi tùy chỉnh

Tạo các lớp lỗi tùy chỉnh cho phép bạn biểu diễn các loại lỗi khác nhau chính xác hơn. Lỗi tùy chỉnh có thể bao gồm các thuộc tính hoặc phương thức bổ sung, có thể giúp xác định và xử lý các vấn đề cụ thể.

class CustomError extends Error {
  constructor(public message: string, public code: number) {
    super(message);
    this.name = 'CustomError';
  }
}

function throwError() {
  throw new CustomError('Something went wrong', 500);
}

try {
  throwError();
} catch (error) {
  if (error instanceof CustomError) {
    console.error(`Error: ${error.message}, Code: ${error.code}`);
  } else {
    console.error('Unexpected error:', error);
  }
}

Trong ví dụ này, CustomError mở rộng lớp Error tích hợp sẵn và thêm thuộc tính code để chỉ định mã lỗi.

2. Xử lý lỗi trong mã không đồng bộ

Mã không đồng bộ thường yêu cầu xử lý lỗi đặc biệt. Sử dụng asyncawait cùng với các khối try-catch có thể đơn giản hóa việc xử lý lỗi trong các hoạt động không đồng bộ.

async function fetchData(url: string): Promise {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new CustomError('Failed to fetch data', response.status);
    }
    const data = await response.json();
    console.log(data);
  } catch (error) {
    if (error instanceof CustomError) {
      console.error(`Error: ${error.message}, Code: ${error.code}`);
    } else {
      console.error('Unexpected error:', error);
    }
  }
}

fetchData('https://api.example.com/data');

Ví dụ này trình bày cách xử lý lỗi từ lệnh gọi fetch không đồng bộ bằng cách sử dụng async, awaittry-catch.

3. Giới hạn lỗi trong React với TypeScript

Khi làm việc với React và TypeScript, ranh giới lỗi giúp bắt lỗi trong cây thành phần và hiển thị UI dự phòng. Việc triển khai ranh giới lỗi với TypeScript đảm bảo an toàn kiểu và xử lý lỗi phù hợp.

import React, { Component, ErrorInfo } from 'react';

interface Props {}

interface State {
  hasError: boolean;
}

class ErrorBoundary extends Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(): State {
    return { hasError: true };
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
    console.error('Error caught by boundary:', error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>
    }

    return this.props.children;
  }
}

export default ErrorBoundary;

Trong ví dụ React này, thành phần ErrorBoundary sẽ phát hiện lỗi trong các thành phần con của nó và hiển thị giao diện người dùng dự phòng nếu xảy ra lỗi.

4. Sử dụng Type Guards cho các loại lỗi

Type guards giúp thu hẹp loại lỗi trong TypeScript. Điều này đặc biệt hữu ích khi xử lý lỗi với các loại khác nhau hoặc từ nhiều nguồn khác nhau.

function isCustomError(error: any): error is CustomError {
  return error instanceof CustomError;
}

try {
  throw new CustomError('Example error', 400);
} catch (error) {
  if (isCustomError(error)) {
    console.error(`CustomError: ${error.message}, Code: ${error.code}`);
  } else {
    console.error('Unknown error:', error);
  }
}

Hàm isCustomError là hàm bảo vệ kiểu giúp xác định xem lỗi phát hiện có phải là trường hợp của CustomError hay không.

5. Xử lý lỗi tập trung

Đối với các ứng dụng lớn, việc tập trung xử lý lỗi có thể đơn giản hóa việc quản lý lỗi và đảm bảo tính nhất quán. Điều này có thể được thực hiện bằng cách sử dụng phần mềm trung gian trong Express.js hoặc trình xử lý lỗi toàn cục trong các khuôn khổ khác.

import express, { Request, Response, NextFunction } from 'express';

const app = express();

app.use((err: any, req: Request, res: Response, next: NextFunction) => {
  console.error('Centralized Error:', err.message);
  res.status(500).send('Internal Server Error');
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

Ví dụ này trình bày trình xử lý lỗi tập trung cho ứng dụng Express.js. Nó bắt tất cả lỗi và phản hồi bằng một thông báo chung.

Phần kết luận

Các kỹ thuật xử lý lỗi nâng cao trong TypeScript tăng cường tính mạnh mẽ của ứng dụng của bạn bằng cách cung cấp nhiều quyền kiểm soát hơn đối với việc quản lý lỗi. Các lớp lỗi tùy chỉnh, xử lý lỗi không đồng bộ, sử dụng ranh giới lỗi trong React, bảo vệ kiểu và xử lý lỗi tập trung là các chiến lược thiết yếu để quản lý lỗi hiệu quả. Việc triển khai các kỹ thuật này sẽ dẫn đến mã dễ bảo trì và đáng tin cậy hơn.