Web Error Handling
Error Handling Basics
1. Use try-catch
All asynchronous operations should use try-catch for error handling:
javascript
try {
const config = new EngineConfig({
appId: 'your-app-id',
appKey: 'your-app-key'
});
const engine = new BeautyEffectEngine(config);
await engine.init();
console.log('Engine initialized successfully');
} catch (error) {
if (error instanceof FacebetterError) {
console.error('Facebetter error:', error.message);
console.error('Error code:', error.code);
} else {
console.error('Unknown error:', error);
}
}2. Check Engine Initialization
javascript
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('Engine initialization failed');
}
} catch (error) {
console.error('Engine initialization failed:', error);
// Handle error, e.g., show user prompt
showErrorToUser('Beauty engine initialization failed, please refresh the page and try again');
}3. Check API Call Results
javascript
try {
engine.setBeautyTypeEnabled(BeautyType.Basic, true);
console.log('Successfully enabled basic beauty');
} catch (error) {
console.error('Failed to enable basic beauty:', error);
// Handle error
}
try {
engine.setBasicParam(BasicParam.Whitening, 0.5);
} catch (error) {
console.error('Failed to set parameter:', error);
}Common Error Codes
FacebetterError Error Codes
FacebetterError error codes can be numbers or strings:
Numeric error codes (from WASM layer):
- 0: Success
- -1: General error (engine not initialized, invalid parameters, etc.)
- Other negative numbers: Error codes returned by specific operations
String error codes (from JS layer):
- 'TIMEOUT': Operation timeout (WASM loading timeout, authentication timeout, etc.)
- 'NETWORK_ERROR': Network error (online authentication failure, etc.)
- 'WASM_LOAD_ERROR': WASM module loading failed
- 'LICENSE_ERROR': License verification failed
- 'AUTH_TIMEOUT': Online authentication timeout
- 'AUTH_EMPTY_RESPONSE': Online authentication returned empty response
- 'ENGINE_CREATE_FAILED': Engine creation failed (may be due to license or resource path issues)
- 'UNKNOWN_ERROR': Unknown error
javascript
try {
await engine.init();
} catch (error) {
if (error instanceof FacebetterError) {
if (typeof error.code === 'string') {
// String error code
switch (error.code) {
case 'TIMEOUT':
console.error('Operation timeout:', error.message);
break;
case 'NETWORK_ERROR':
console.error('Network error:', error.message);
break;
case 'WASM_LOAD_ERROR':
console.error('WASM loading failed:', error.message);
break;
case 'LICENSE_ERROR':
case 'ENGINE_CREATE_FAILED':
console.error('License error:', error.message);
break;
default:
console.error('Error:', error.code, error.message);
}
} else {
// Numeric error code
switch (error.code) {
case -1:
console.error('General error:', error.message);
break;
default:
console.error('Error code:', error.code, error.message);
}
}
}
}Image Data Error Handling
1. Input Image Validation
javascript
function validateImageData(imageData) {
if (!imageData) {
throw new Error('Image data cannot be empty');
}
if (!(imageData instanceof ImageData)) {
throw new Error('Image data must be ImageData type');
}
if (imageData.width <= 0 || imageData.height <= 0) {
throw new Error('Invalid image dimensions');
}
if (!imageData.data || imageData.data.length === 0) {
throw new Error('Image data is empty');
}
return true;
}
function processImageSafe(imageData, engine) {
try {
// Validate input
validateImageData(imageData);
// Process image (synchronous method)
const result = engine.processImage(
imageData,
imageData.width,
imageData.height,
ProcessMode.Video
);
return result;
} catch (error) {
console.error('Image processing failed:', error);
throw error;
}
}2. Canvas Error Handling
javascript
function getImageDataFromCanvas(canvas) {
try {
if (!canvas) {
throw new Error('Canvas element does not exist');
}
const ctx = canvas.getContext('2d');
if (!ctx) {
throw new Error('Cannot get Canvas context');
}
if (canvas.width === 0 || canvas.height === 0) {
throw new Error('Invalid Canvas dimensions');
}
return ctx.getImageData(0, 0, canvas.width, canvas.height);
} catch (error) {
console.error('Failed to get Canvas image data:', error);
throw error;
}
}Network Error Handling
1. Online Verification Error
javascript
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(`Initialization failed (attempt ${i + 1}/${maxRetries}):`, error.message);
if (i < maxRetries - 1) {
// Wait before retry
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
continue;
}
}
throw error;
}
}
}
// Usage
try {
const engine = await initEngineWithRetry(config);
} catch (error) {
console.error('Initialization failed after multiple retries:', error);
}2. WASM Loading Error
javascript
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 loading failed:', error);
// Can try to reload or use fallback solution
showErrorToUser('Beauty feature temporarily unavailable, please refresh the page and try again');
}
throw error;
}
}Error Handling Best Practices
1. Unified Error Handler
javascript
class ErrorHandler {
static handle(error, context = '') {
console.error(`[${context}] Error:`, error);
if (error instanceof FacebetterError) {
// Facebetter specific error
this.handleFacebetterError(error, context);
} else if (error instanceof Error) {
// General error
this.handleGenericError(error, context);
} else {
// Unknown error
console.error('Unknown error type:', error);
}
}
static handleFacebetterError(error, context) {
switch (error.code) {
case -1:
console.error('Facebetter general error:', error.message);
break;
default:
console.error('Facebetter error:', error.code, error.message);
}
}
static handleGenericError(error, context) {
if (error.message.includes('network')) {
console.error('Network error:', error.message);
} else if (error.message.includes('WASM')) {
console.error('WASM error:', error.message);
} else {
console.error('General error:', error.message);
}
}
}
// Usage
try {
await engine.init();
} catch (error) {
ErrorHandler.handle(error, 'Engine initialization');
}2. User-Friendly Error Messages
javascript
function showErrorToUser(message) {
// Show user-friendly error message
const errorDiv = document.createElement('div');
errorDiv.className = 'error-message';
errorDiv.textContent = message;
document.body.appendChild(errorDiv);
// Auto-hide after 3 seconds
setTimeout(() => {
errorDiv.remove();
}, 3000);
}
try {
await engine.init();
} catch (error) {
let userMessage = 'Beauty engine initialization failed';
if (error.message.includes('network')) {
userMessage = 'Network connection failed, please check network and try again';
} else if (error.message.includes('WASM')) {
userMessage = 'Browser not supported or loading failed, please refresh the page and try again';
} else if (error.message.includes('appId') || error.message.includes('appKey')) {
userMessage = 'Configuration error, please contact technical support';
}
showErrorToUser(userMessage);
console.error('Detailed error:', error);
}3. Error Logging
javascript
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
};
// Send to server (optional)
if (window.fetch) {
fetch('/api/errors', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(errorLog)
}).catch(err => console.error('Failed to send error log:', err));
}
// Console output
console.error('Error log:', errorLog);
}
}
// Usage
try {
await engine.init();
} catch (error) {
ErrorLogger.log(error, 'Engine initialization', {
appId: config.appId ? 'provided' : 'missing'
});
}Preventive Error Handling
1. Parameter Validation
javascript
function validateBeautyParam(value) {
if (typeof value !== 'number') {
throw new TypeError('Parameter value must be a number');
}
if (value < 0.0 || value > 1.0) {
throw new RangeError('Parameter value must be between 0.0-1.0');
}
return true;
}
function setBasicParamSafe(engine, param, value) {
try {
validateBeautyParam(value);
engine.setBasicParam(param, value);
} catch (error) {
console.error('Failed to set parameter:', error);
throw error;
}
}2. State Checking
javascript
function processImageWithValidation(engine, imageData) {
if (!engine) {
throw new Error('Engine not created');
}
if (!engine.initialized) {
throw new Error('Engine not initialized');
}
if (!imageData) {
throw new Error('Image data cannot be empty');
}
// Process image (synchronous method)
return engine.processImage(
imageData,
imageData.width,
imageData.height,
ProcessMode.Video
);
}Related Documentation
- Best Practices - Performance optimization and error prevention
- FAQ - Common errors and solutions
- API Reference - Complete API documentation