ArkTS中如何优雅处理异常和错误

2025-06发布2次浏览

在ArkTS(HarmonyOS的TypeScript开发框架)中,优雅地处理异常和错误是构建健壮、可靠应用的重要环节。良好的错误处理机制不仅可以提升用户体验,还能帮助开发者快速定位问题并进行修复。以下将详细介绍如何在ArkTS中优雅处理异常和错误。


1. 异常与错误的基本概念

在编程中,异常(Exception)通常指的是程序运行时发生的意外情况,而错误(Error)则可以指代更广义的问题,包括逻辑错误或外部依赖问题。在ArkTS中,异常和错误可以通过JavaScript/TypeScript中的try...catch语句捕获,并通过自定义错误类来扩展。


2. 使用 try...catch 捕获同步错误

最基础的异常处理方式是使用try...catch结构来捕获同步代码中的错误。例如:

function divide(a: number, b: number): number {
    if (b === 0) {
        throw new Error("Division by zero is not allowed");
    }
    return a / b;
}

try {
    const result = divide(10, 0);
    console.log(result);
} catch (error) {
    console.error("An error occurred:", error.message);
}

上述代码展示了如何捕获除零错误,并通过console.error输出错误信息。这种方式适用于同步代码块中的错误处理。


3. 处理异步错误:Promiseasync/await

在现代JavaScript/TypeScript开发中,异步操作非常常见。对于异步错误,可以使用Promise.catchasync/await结合try...catch来捕获错误。

3.1 使用 Promise.catch

function fetchData(url: string): Promise<string> {
    return new Promise((resolve, reject) => {
        // 模拟网络请求失败
        setTimeout(() => reject(new Error("Network request failed")), 1000);
    });
}

fetchData("https://example.com/api")
    .then(data => console.log("Data:", data))
    .catch(error => console.error("Fetch error:", error.message));

3.2 使用 async/await

async function fetchAndProcessData(url: string): Promise<void> {
    try {
        const data = await fetchData(url);
        console.log("Processed Data:", data);
    } catch (error) {
        console.error("Error during data processing:", error.message);
    }
}

fetchAndProcessData("https://example.com/api");

async/await语法让异步代码看起来更像同步代码,从而提高代码可读性和维护性。


4. 自定义错误类

为了更清晰地标识不同类型的错误,可以创建自定义错误类。这有助于在复杂的项目中区分不同的错误来源。

class APIError extends Error {
    statusCode: number;

    constructor(message: string, statusCode: number) {
        super(message);
        this.statusCode = statusCode;
        this.name = "APIError";
    }
}

function handleAPIResponse(response: Response): void {
    if (!response.ok) {
        throw new APIError("API request failed", response.status);
    }
}

// 使用示例
try {
    const response = await fetch("https://example.com/api");
    handleAPIResponse(response);
} catch (error) {
    if (error instanceof APIError) {
        console.error(`API Error: ${error.message}, Status Code: ${error.statusCode}`);
    } else {
        console.error("Unexpected error:", error.message);
    }
}

通过自定义错误类,我们可以为每种错误类型添加额外的上下文信息(如HTTP状态码),从而简化调试过程。


5. 全局错误处理

在大型应用中,全局错误处理尤为重要。ArkTS支持通过@Entry装饰器定义页面入口组件,并可以在应用级别设置全局错误捕获机制。

5.1 全局未捕获异常处理

可以使用window.addEventListener('unhandledrejection', ...)来捕获未处理的Promise拒绝事件。

window.addEventListener('unhandledrejection', (event) => {
    console.error("Unhandled Rejection at:", event.promise, "reason:", event.reason);
});

5.2 全局错误边界

在React或Vue等框架中,通常有“错误边界”组件来捕获子组件中的错误。虽然ArkTS本身没有直接提供类似功能,但可以通过封装页面组件的方式实现类似效果。

@Entry
@Component
struct SafePage {
    @State errorMessage: string = "";

    private componentDidCatch(error: any): void {
        this.errorMessage = error.message;
    }

    build() {
        Column() {
            if (this.errorMessage) {
                Text(this.errorMessage).fontSize(20).color(Color.red);
            } else {
                Text("Page Content").fontSize(20);
            }
        }
    }
}

6. 日志记录与监控

除了在代码中捕获错误外,还应将错误信息记录到日志系统中,以便后续分析。可以使用第三方库(如log4js)或自定义日志工具来实现。

import * as fs from "fs";

function logError(error: Error): void {
    const logMessage = `[${new Date().toISOString()}] - ${error.message}\n`;
    fs.appendFileSync("error.log", logMessage);
}

try {
    // 可能抛出错误的代码
} catch (error) {
    logError(error);
    console.error("Error logged:", error.message);
}

此外,还可以集成错误监控服务(如Sentry、Bugsnag)来实时跟踪线上环境中的错误。


7. 总结

通过合理使用try...catch、自定义错误类、全局错误处理以及日志记录等技术手段,可以在ArkTS中实现优雅的异常和错误处理机制。这些方法不仅能够提升代码质量,还能增强用户体验和系统的稳定性。