TypeScript上級

上級 TypeScriptで学ぶ例外設計|アンチパターン編

導入

例外処理は、プログラムの堅牢性を確保するために不可欠な要素です。特に、TypeScriptのような静的型付け言語においては、型の安全性を利用して例外を管理することが可能です。しかし、実務ではしばしば例外処理に関するアンチパターンに陥りがちです。本記事では、上級者向けにTypeScriptを用いた例外設計の具体的なアンチパターンを取り上げ、それを改善する方法について考察します。

教科書レベルの解説(例外設計)

重要な概念の整理

例外設計においては、例外の発生を適切に管理することが求められます。例外は、予期しない状況を示すものであり、これを適切に処理することでシステムの安定性を保ちます。TypeScriptでは、try-catch文を用いて例外を捕捉し、適切なエラーハンドリングを行うことが一般的ですが、これに伴うアンチパターンも存在します。

コード例(TypeScript)


function fetchData(url: string): Promise {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (url === "valid-url") {
                resolve("Data fetched successfully");
            } else {
                reject(new Error("Invalid URL"));
            }
        }, 1000);
    });
}

async function main() {
    try {
        const data = await fetchData("invalid-url");
        console.log(data);
    } catch (error) {
        console.error("Error occurred:", error);
    }
}
main();

コードの行ごとの解説

  1. fetchData関数は、指定されたURLからデータを取得するためのPromiseを返します。
  2. setTimeoutを使用して非同期処理を模擬し、URLが有効であるかどうかをチェックします。
  3. 無効なURLの場合、rejectを呼び出してエラーを発生させます。
  4. main関数では、fetchDataを呼び出し、その結果を取得します。
  5. try-catchブロックを用いて、エラーが発生した場合に適切に処理します。

アンチパターン編

上記のコードには、一般的なアンチパターンが含まれています。例えば、エラー処理が単にコンソールにエラーを出力するだけに留まっています。このアプローチは、エラーの詳細な情報をユーザーに提供しないため、デバッグが難しくなります。

さらに、fetchData関数が返すエラーの種類が決まっていないため、エラーの内容に応じた適切な処理が行えません。これにより、エラーの特定や修正が困難になります。

改善策として、エラーをより詳細に分類し、ユーザーにフィードバックを提供するようにします。以下のように、エラーオブジェクトにカスタムプロパティを追加することが考えられます。


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

function fetchData(url: string): Promise {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (url === "valid-url") {
                resolve("Data fetched successfully");
            } else {
                reject(new CustomError(404, "Invalid URL"));
            }
        }, 1000);
    });
}

async function main() {
    try {
        const data = await fetchData("invalid-url");
        console.log(data);
    } catch (error) {
        if (error instanceof CustomError) {
            console.error(`Error ${error.code}: ${error.message}`);
        } else {
            console.error("Unexpected error:", error);
        }
    }
}
main();

まとめ

  • 例外処理においては、エラーの詳細を把握し、適切なフィードバックを行うことが重要です。
  • カスタムエラークラスを使用することで、エラーの種類を明確にし、より効果的なエラーハンドリングが可能になります。
  • TypeScriptの型システムを活用し、エラー処理を強化することが、堅牢なアプリケーションの実現に寄与します。