Avoid complex, multi-layered error handling that obscures error origins and makes debugging difficult. Each error should be handled at the most appropriate level without unnecessary re-parsing or nested try-catch blocks.

Problems with complex error flows:

Instead, handle errors close to their source and use clear, single-responsibility error handling:

// โŒ Avoid: Complex nested error handling
async parseFile(fileId: string): Promise<LobeDocument> {
  try {
    const { filePath, file, cleanup } = await this.fileService.downloadFileToLocal(fileId);
    try {
      const fileDocument = await loadFile(filePath);
      // ... processing
    } catch (error) {
      console.error(`File parsing failed:`, error);
      throw error;
    } finally {
      cleanup();
    }
  } catch (error) {
    console.error(`File not found:`, error);
    throw error;
  }
}

// โœ… Better: Single-level error handling with clear responsibility
async parseFile(fileId: string): Promise<LobeDocument> {
  const { filePath, file, cleanup } = await this.fileService.downloadFileToLocal(fileId);
  
  try {
    const fileDocument = await loadFile(filePath);
    // ... processing
    return document;
  } catch (error) {
    console.error(`[${file.name}] File parsing failed:`, error);
    throw error;
  } finally {
    cleanup();
  }
}

Keep error handling flows simple and direct to improve code maintainability and debugging experience.