掌握优雅的错误处理和资源管理技巧
// 基本用法
try {
// 可能抛出错误的代码
const result = 10 / 0;
} catch (error) {
// 处理错误
console.error(error);
} finally {
// 无论是否出错都会执行的代码
console.log('操作完成');
}
// 异步错误处理
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
} catch (error) {
console.error('Fetch error:', error);
throw error;
}
}// 自定义错误类
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.name = 'AppError';
this.statusCode = statusCode;
this.status = statusCode >= 400 && statusCode < 500 ? 'fail' : 'error';
Error.captureStackTrace(this, this.constructor);
}
}
// 使用自定义错误
function divide(a, b) {
if (b === 0) {
throw new AppError('除数不能为零', 400);
}
return a / b;
}
try {
divide(10, 0);
} catch (error) {
if (error instanceof AppError) {
console.error(error.statusCode, error.message);
} else {
console.error(error);
}
}// 错误原因链
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error('Network response was not ok', {
cause: { status: response.status, statusText: response.statusText }
});
}
} catch (error) {
console.error(error.message);
console.error(error.cause);
}
// 嵌套错误
try {
try {
throw new Error('Inner error');
} catch (innerError) {
throw new Error('Outer error', { cause: innerError });
}
} catch (outerError) {
console.error(outerError.message); // Outer error
console.error(outerError.cause.message); // Inner error
}// 实现 Disposable 接口
class FileHandle {
constructor(filename) {
this.filename = filename;
this.handle = null;
}
async open() {
// 模拟打开文件
this.handle = 'file handle';
console.log(`Opening file ${this.filename}`);
return this;
}
close() {
if (this.handle) {
console.log(`Closing file ${this.filename}`);
this.handle = null;
}
}
[Symbol.dispose]() {
this.close();
}
}
// 使用 using 关键字
async function processFile() {
using fileHandle = await new FileHandle('data.txt').open();
// 使用 fileHandle
console.log('Processing file...');
// 函数结束时,fileHandle 会自动关闭
}
processFile();