> ## Documentation Index
> Fetch the complete documentation index at: https://docs.facebetter.net/llms.txt
> Use this file to discover all available pages before exploring further.

# 错误处理

> Web 美颜 SDK 错误处理指南

## 错误处理基础

### 1. 使用 try-catch

所有异步操作都应该使用 try-catch 进行错误处理：

```javascript theme={null}
try {
    const config = new EngineConfig({
        appId: 'your-app-id',
        appKey: 'your-app-key'
        // 可选：如果提供了 licenseJson，则优先使用授权数据验证
        // licenseJson: 'your license json string'
    });
    
    const engine = new BeautyEffectEngine(config);
    await engine.init();
    
    console.log('引擎初始化成功');
} catch (error) {
    if (error instanceof FacebetterError) {
        console.error('Facebetter 错误:', error.message);
        console.error('错误代码:', error.code);
    } else {
        console.error('未知错误:', error);
    }
}
```

### 2. 检查引擎初始化

```javascript theme={null}
let engine = null;

try {
    const config = new EngineConfig({
        appId: 'your-app-id',
        appKey: 'your-app-key'
    });
    
    engine = new BeautyEffectEngine(config);
    await engine.init();
    
    if (!engine || !engine.initialized) {
        throw new Error('引擎初始化失败');
    }
} catch (error) {
    console.error('引擎初始化失败:', error);
    // 处理错误，如显示用户提示
    showErrorToUser('美颜引擎初始化失败，请刷新页面重试');
}
```

### 3. 检查 API 调用结果

```javascript theme={null}
try {
    engine.setBasicParam(BasicParam.Smoothing, 0.5);
    console.log('成功设置磨皮参数');
} catch (error) {
    console.error('设置参数失败:', error);
    // 处理错误
}

try {
    engine.setBasicParam(BasicParam.Whitening, 0.5);
} catch (error) {
    console.error('设置参数失败:', error);
}
```

## 常见错误码

### FacebetterError 错误码

FacebetterError 的错误码可以是数字或字符串：

**数字错误码**（来自 WASM 层）：

* **0**: 成功
* **-1**: 通用错误（引擎未初始化、参数无效等）
* **其他负数**: 根据具体操作返回的错误码

**字符串错误码**（来自 JS 层）：

* **'TIMEOUT'**: 操作超时（WASM 加载超时、认证超时等）
* **'NETWORK\_ERROR'**: 网络错误（在线认证失败等）
* **'WASM\_LOAD\_ERROR'**: WASM 模块加载失败
* **'LICENSE\_ERROR'**: 许可证验证失败
* **'AUTH\_TIMEOUT'**: 在线认证超时
* **'AUTH\_EMPTY\_RESPONSE'**: 在线认证返回空响应
* **'ENGINE\_CREATE\_FAILED'**: 引擎创建失败（可能是许可证或资源路径问题）
* **'UNKNOWN\_ERROR'**: 未知错误

```javascript theme={null}
try {
    await engine.init();
} catch (error) {
    if (error instanceof FacebetterError) {
        if (typeof error.code === 'string') {
            // 字符串错误码
            switch (error.code) {
                case 'TIMEOUT':
                    console.error('操作超时:', error.message);
                    break;
                case 'NETWORK_ERROR':
                    console.error('网络错误:', error.message);
                    break;
                case 'WASM_LOAD_ERROR':
                    console.error('WASM 加载失败:', error.message);
                    break;
                case 'LICENSE_ERROR':
                case 'ENGINE_CREATE_FAILED':
                    console.error('许可证错误:', error.message);
                    break;
                default:
                    console.error('错误:', error.code, error.message);
            }
        } else {
            // 数字错误码
            switch (error.code) {
                case -1:
                    console.error('通用错误:', error.message);
                    break;
                default:
                    console.error('错误码:', error.code, error.message);
            }
        }
    }
}
```

## 处理图像数据错误

### 1. 输入图像验证

```javascript theme={null}
function validateImageData(imageData) {
    if (!imageData) {
        throw new Error('图像数据不能为空');
    }
    
    if (!(imageData instanceof ImageData)) {
        throw new Error('图像数据必须是 ImageData 类型');
    }
    
    if (imageData.width <= 0 || imageData.height <= 0) {
        throw new Error('图像尺寸无效');
    }
    
    if (!imageData.data || imageData.data.length === 0) {
        throw new Error('图像数据为空');
    }
    
    return true;
}

function processImageSafe(imageData, engine) {
    try {
        // 验证输入
        validateImageData(imageData);
        
        // 处理图像（同步方法）
        const result = engine.processImage(
            imageData, 
            imageData.width, 
            imageData.height, 
            FrameType.Video
        );
        
        return result;
    } catch (error) {
        console.error('图像处理失败:', error);
        throw error;
    }
}
```

### 2. Canvas 错误处理

```javascript theme={null}
function getImageDataFromCanvas(canvas) {
    try {
        if (!canvas) {
            throw new Error('Canvas 元素不存在');
        }
        
        const ctx = canvas.getContext('2d');
        if (!ctx) {
            throw new Error('无法获取 Canvas 上下文');
        }
        
        if (canvas.width === 0 || canvas.height === 0) {
            throw new Error('Canvas 尺寸无效');
        }
        
        return ctx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (error) {
        console.error('获取 Canvas 图像数据失败:', error);
        throw error;
    }
}
```

## 网络错误处理

### 1. 在线验证错误

```javascript theme={null}
async function initEngineWithRetry(config, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
        try {
            const engine = new BeautyEffectEngine(config);
            await engine.init();
            return engine;
        } catch (error) {
            if (error.message.includes('network') || error.message.includes('fetch')) {
                console.warn(`初始化失败（尝试 ${i + 1}/${maxRetries}）:`, error.message);
                
                if (i < maxRetries - 1) {
                    // 等待后重试
                    await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
                    continue;
                }
            }
            
            throw error;
        }
    }
}

// 使用
try {
    const engine = await initEngineWithRetry(config);
} catch (error) {
    console.error('初始化失败，已重试多次:', error);
}
```

### 2. WASM 加载错误

```javascript theme={null}
async function loadEngineWithFallback() {
    try {
        const engine = new BeautyEffectEngine(config);
        await engine.init();
        return engine;
    } catch (error) {
        if (error.message.includes('WASM') || error.message.includes('wasm')) {
            console.error('WASM 加载失败:', error);
            // 可以尝试重新加载或使用备用方案
            showErrorToUser('美颜功能暂时不可用，请刷新页面重试');
        }
        throw error;
    }
}
```

## 错误处理最佳实践

### 1. 统一错误处理函数

```javascript theme={null}
class ErrorHandler {
    static handle(error, context = '') {
        console.error(`[${context}] 错误:`, error);
        
        if (error instanceof FacebetterError) {
            // Facebetter 特定错误
            this.handleFacebetterError(error, context);
        } else if (error instanceof Error) {
            // 通用错误
            this.handleGenericError(error, context);
        } else {
            // 未知错误
            console.error('未知错误类型:', error);
        }
    }
    
    static handleFacebetterError(error, context) {
        switch (error.code) {
            case -1:
                console.error('Facebetter 通用错误:', error.message);
                break;
            default:
                console.error('Facebetter 错误:', error.code, error.message);
        }
    }
    
    static handleGenericError(error, context) {
        if (error.message.includes('network')) {
            console.error('网络错误:', error.message);
        } else if (error.message.includes('WASM')) {
            console.error('WASM 错误:', error.message);
        } else {
            console.error('通用错误:', error.message);
        }
    }
}

// 使用
try {
    await engine.init();
} catch (error) {
    ErrorHandler.handle(error, '引擎初始化');
}
```

### 2. 用户友好的错误提示

```javascript theme={null}
function showErrorToUser(message) {
    // 显示用户友好的错误提示
    const errorDiv = document.createElement('div');
    errorDiv.className = 'error-message';
    errorDiv.textContent = message;
    document.body.appendChild(errorDiv);
    
    // 3秒后自动隐藏
    setTimeout(() => {
        errorDiv.remove();
    }, 3000);
}

try {
    await engine.init();
} catch (error) {
    let userMessage = '美颜功能初始化失败';
    
    if (error.message.includes('network')) {
        userMessage = '网络连接失败，请检查网络后重试';
    } else if (error.message.includes('WASM')) {
        userMessage = '浏览器不支持或加载失败，请刷新页面重试';
    } else if (error.message.includes('appId') || error.message.includes('appKey')) {
        userMessage = '配置错误，请联系技术支持';
    }
    
    showErrorToUser(userMessage);
    console.error('详细错误:', error);
}
```

### 3. 错误日志记录

```javascript theme={null}
class ErrorLogger {
    static log(error, context = '', userInfo = {}) {
        const errorLog = {
            timestamp: new Date().toISOString(),
            context: context,
            error: {
                message: error.message,
                code: error.code || 'N/A',
                stack: error.stack
            },
            userInfo: userInfo,
            userAgent: navigator.userAgent,
            url: window.location.href
        };
        
        // 发送到服务器（可选）
        if (window.fetch) {
            fetch('/api/errors', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(errorLog)
            }).catch(err => console.error('发送错误日志失败:', err));
        }
        
        // 控制台输出
        console.error('错误日志:', errorLog);
    }
}

// 使用
try {
    await engine.init();
} catch (error) {
    ErrorLogger.log(error, '引擎初始化', {
        appId: config.appId ? 'provided' : 'missing'
    });
}
```

## 预防性错误处理

### 1. 参数验证

```javascript theme={null}
function validateBeautyParam(value) {
    if (typeof value !== 'number') {
        throw new TypeError('参数值必须是数字');
    }
    
    if (value < 0 || value > 1) {
        throw new RangeError('参数值必须在 0.0-1.0 之间');
    }
    
    return true;
}

function setBasicParamSafe(engine, param, value) {
    try {
        validateBeautyParam(value);
        engine.setBasicParam(param, value);
    } catch (error) {
        console.error('设置参数失败:', error);
        throw error;
    }
}
```

### 2. 状态检查

```javascript theme={null}
function processImageWithValidation(engine, imageData) {
    if (!engine) {
        throw new Error('引擎未创建');
    }
    
    if (!engine.initialized) {
        throw new Error('引擎未初始化');
    }
    
    if (!imageData) {
        throw new Error('图像数据不能为空');
    }
    
    // 处理图像（同步方法）
    return engine.processImage(
        imageData, 
        imageData.width, 
        imageData.height, 
        FrameType.Video
    );
}
```

## 相关文档

* [最佳实践](/zh/web/best-practices) - 性能优化和错误预防
* [常见问题](/zh/web/faq) - 常见错误和解决方案
* [API 参考](/zh/web/api-reference) - 完整的 API 文档
