最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

UnError如何讓JavaScript錯誤處理更優(yōu)雅詳解

 更新時間:2025年11月29日 10:19:09   作者:會功夫的李白  
UnError是一個現(xiàn)代化的JavaScript錯誤處理庫,解決標準Error的諸多痛點,這篇文章主要介紹了UnError如何讓JavaScript錯誤處理更優(yōu)雅的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

一個輕量級、類型安全的統(tǒng)一錯誤處理庫

痛點:JavaScript 錯誤處理的困境

作為一名 JavaScript/TypeScript 開發(fā)者,你一定遇到過這些令人頭疼的問題:

問題 1:錯誤信息貧乏

throw new Error('User not found');

這個錯誤告訴了我們什么?只有一句話。我們不知道:

  • 什么時候發(fā)生的?
  • 在哪個模塊?
  • 有沒有更詳細的上下文?
  • 根本原因是什么?

問題 2:錯誤鏈追蹤困難

try {
  await database.connect();
} catch (err) {
  // 原始錯誤信息丟失了!
  throw new Error('Failed to fetch user');
}

當錯誤在多層調(diào)用中傳遞時,我們往往會丟失原始的錯誤信息。

問題 3:錯誤無法序列化

const error = new Error('Something went wrong');
const json = JSON.stringify(error);
console.log(json); // "{}" - 空對象!

標準的 Error 對象無法被 JSON 序列化,這在分布式系統(tǒng)中是個大問題。

問題 4:微服務(wù)間錯誤傳遞麻煩

在微服務(wù)架構(gòu)中,錯誤需要在不同服務(wù)之間傳遞。但標準 Error 對象:

  • 無法序列化
  • 無法保留完整的錯誤鏈
  • 無法攜帶額外的上下文信息

解決方案:UnError

UnError 是一個現(xiàn)代化的 JavaScript 錯誤處理庫,它解決了標準 Error 的諸多痛點:

  • ?? 簡潔的 API - 學(xué)習(xí)成本低,上手快
  • ?? 完整的錯誤鏈 - 追蹤錯誤的來龍去脈
  • ?? 可序列化 - 完美支持分布式系統(tǒng)
  • ?? 格式化輸出 - 人類可讀的錯誤描述
  • ?? 類型安全 - 完整的 TypeScript 支持
  • ?? 零依賴 - 輕量級,不引入額外負擔(dān)
  • ?? 高質(zhì)量 - 97%+ 測試覆蓋率

無論你是在開發(fā)單體應(yīng)用還是微服務(wù)架構(gòu),UnError 都能讓你的錯誤處理更加優(yōu)雅和高效。

快速開始

安裝

npm install unerror

基本用法

import { UnError, createError, error } from 'unerror';

// 創(chuàng)建錯誤
const error1 = new UnError('User not found');

// 帶因果錯誤
try {
  await database.query('SELECT * FROM users');
} catch (err) {
  throw new UnError('Failed to fetch user', err);
  // 你甚至可以
  throw createError('Failed to fetch user', err);
  // 或
  throw error('Failed to fetch user', err);
}

核心功能詳解

1. 錯誤鏈追蹤

UnError 最強大的功能之一就是錯誤鏈追蹤。它可以完整記錄錯誤的傳播路徑:

// 第一層:數(shù)據(jù)庫錯誤
const dbError = new Error('Connection timeout');

// 第二層:查詢錯誤
const queryError = new UnError('Query execution failed', dbError);

// 第三層:服務(wù)錯誤
const serviceError = new UnError('User service error', queryError);

// 第四層:API 錯誤
const apiError = new UnError('API request failed', serviceError);

// 獲取完整的錯誤鏈
const chain = apiError.getErrorChain();
console.log(`錯誤鏈深度: ${chain.length}`); // 4

// 遍歷錯誤鏈
chain.forEach((err, index) => {
  console.log(`[${index}] ${err.message}`);
});

輸出:

[0] API request failed
[1] User service error
[2] Query execution failed
[3] Connection timeout

2. 序列化和反序列化

UnError 可以完美地序列化為 JSON,這對分布式系統(tǒng)至關(guān)重要:

// 服務(wù) A:創(chuàng)建錯誤并序列化
const error = new UnError('Database connection failed');
const json = JSON.stringify(error.toJSON());

// 通過網(wǎng)絡(luò)傳輸?shù)椒?wù) B...
await fetch('/api/log', {
  method: 'POST',
  body: json
});

// 服務(wù) B:接收并反序列化
const data = JSON.parse(receivedJson);
const restored = UnError.fromJSON(data);

// 完整保留了所有信息
console.log(restored.message);    // 'Database connection failed'
console.log(restored.timestamp);  // 原始時間戳
console.log(restored.stack);      // 原始堆棧跟蹤

3. 格式化輸出

UnError 提供了多種格式化選項,讓錯誤信息更易讀:

const cause = new Error('Database connection failed');
const error2 = new UnError('Query execution failed', cause);

// 基本格式化
console.log(error.format());

輸出:

UnError: Query execution failed
  Stack:
    at <anonymous> (d:\developer\GitProjects\unerror\examples\04-formatting.ts:30:16)
    at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:337:24)
    at async loadESM (node:internal/process/esm_loader:34:7)
    at async handleMainPromise (node:internal/modules/run_main:106:12)
  Caused by:
    Error: Database connection failed

格式化整個錯誤鏈:

console.log(error.formatChain({ includeStack: false }));

輸出:

UnError: Query execution failed
  ? Error: Database connection failed

4. 堆棧跟蹤解析

UnError 可以解析堆棧跟蹤,提取結(jié)構(gòu)化信息:

const error = new UnError('Something went wrong');
const frames = error.parseStack();

frames.forEach(frame => {
  console.log(`函數(shù): ${frame.functionName}`);
  console.log(`文件: ${frame.fileName}`);
  console.log(`行號: ${frame.lineNumber}`);
  console.log(`列號: ${frame.columnNumber}`);
});

5. 自定義錯誤類

使用工廠函數(shù)快速創(chuàng)建自定義錯誤類:

import { createErrorClass } from 'unerror';

// 創(chuàng)建自定義錯誤類
const DatabaseError = createErrorClass('DatabaseError');
const NetworkError = createErrorClass('NetworkError');
const ValidationError = createErrorClass('ValidationError');

// 使用自定義錯誤類
const dbError = new DatabaseError('Connection failed');
console.log(dbError.name);                    // 'DatabaseError'
console.log(dbError instanceof UnError);      // true
console.log(dbError instanceof DatabaseError); // true

// 自動繼承所有 UnError 功能
console.log(dbError.toJSON());
console.log(dbError.format());

實戰(zhàn)場景

場景 1:Express API 錯誤處理

import express from 'express';
import { UnError } from 'unerror';

const app = express();

// 業(yè)務(wù)邏輯
async function getUserById(id: string) {
  try {
    const user = await database.findUser(id);
    if (!user) {
      throw new UnError('User not found');
    }
    return user;
  } catch (err) {
    throw new UnError('Failed to get user', err as Error);
  }
}

// 路由處理
app.get('/users/:id', async (req, res) => {
  try {
    const user = await getUserById(req.params.id);
    res.json(user);
  } catch (err) {
    if (UnError.isUnError(err)) {
      // 記錄完整的錯誤鏈
      console.error(err.formatChain());
      
      // 返回友好的錯誤信息
      res.status(500).json({
        error: err.message,
        timestamp: err.timestamp
      });
    } else {
      res.status(500).json({ error: 'Internal server error' });
    }
  }
});

場景 2:錯誤監(jiān)控和分析

import { UnError } from 'unerror';

class ErrorMonitor {
  private errors: UnError[] = [];
  
  track(error: Error | UnError): void {
    if (UnError.isUnError(error)) {
      this.errors.push(error);
      this.analyze(error);
    }
  }
  
  analyze(error: UnError): void {
    const chain = error.getErrorChain();
    const frames = error.parseStack();
    
    console.log('=== 錯誤分析報告 ===');
    console.log(`時間: ${new Date(error.timestamp).toISOString()}`);
    console.log(`消息: ${error.message}`);
    console.log(`錯誤鏈深度: ${chain.length}`);
    
    if (frames.length > 0) {
      const topFrame = frames[0];
      console.log(`發(fā)生位置: ${topFrame.fileName}:${topFrame.lineNumber}`);
      console.log(`函數(shù): ${topFrame.functionName || '(anonymous)'}`);
    }
    
    console.log('\n錯誤鏈:');
    chain.forEach((err, index) => {
      console.log(`  ${index + 1}. ${err.message}`);
    });
    
    // 發(fā)送到監(jiān)控服務(wù)
    this.sendToMonitoring(error);
  }
  
  sendToMonitoring(error: UnError): void {
    fetch('https://monitoring.example.com/errors', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(error.toJSON())
    });
  }
  
  getStatistics() {
    return {
      total: this.errors.length,
      byHour: this.groupByHour(),
      topErrors: this.getTopErrors()
    };
  }
  
  private groupByHour() {
    // 按小時分組統(tǒng)計
    const groups = new Map<string, number>();
    this.errors.forEach(error => {
      const hour = new Date(error.timestamp).toISOString().slice(0, 13);
      groups.set(hour, (groups.get(hour) || 0) + 1);
    });
    return Object.fromEntries(groups);
  }
  
  private getTopErrors() {
    // 統(tǒng)計最常見的錯誤
    const counts = new Map<string, number>();
    this.errors.forEach(error => {
      counts.set(error.message, (counts.get(error.message) || 0) + 1);
    });
    return Array.from(counts.entries())
      .sort((a, b) => b[1] - a[1])
      .slice(0, 10);
  }
}

// 使用
const monitor = new ErrorMonitor();

try {
  await someOperation();
} catch (err) {
  const error = new UnError('Operation failed', err as Error);
  monitor.track(error);
}

與原 Error 對比

vs 標準 Error

特性標準 ErrorUnError
基本錯誤信息??
堆棧跟蹤??
時間戳??
錯誤鏈??
序列化??
格式化輸出??
堆棧解析??
TypeScript 支持基礎(chǔ)完整

vs 手動實現(xiàn)

// ? 手動實現(xiàn) - 需要大量代碼
class CustomError extends Error {
  public timestamp: number;
  public cause?: Error;
  
  constructor(message: string, cause?: Error) {
    super(message);
    this.name = 'CustomError';
    this.timestamp = Date.now();
    this.cause = cause;
  }
  
  toJSON() {
    // 需要手動實現(xiàn)序列化
    return {
      name: this.name,
      message: this.message,
      timestamp: this.timestamp,
      stack: this.stack,
      cause: this.cause ? /* 遞歸序列化 */ : undefined
    };
  }
  
  format() {
    // 需要手動實現(xiàn)格式化
    // ...
  }
  
  // 還需要實現(xiàn) fromJSON、getErrorChain、parseStack 等方法
}

// ? UnError - 開箱即用
import { UnError } from 'unerror';
const error = new UnError('Something went wrong');
// 所有功能都已內(nèi)置

技術(shù)細節(jié)

類型安全

UnError 使用 TypeScript 編寫,提供完整的類型定義:

import type {
  UnError,
  SerializedError,
  FormatOptions,
  StackFrame
} from 'unerror';

// 類型守衛(wèi)
function handleError(error: unknown): void {
  if (UnError.isUnError(error)) {
    // TypeScript 知道這里 error 是 UnError 類型
    const timestamp: number = error.timestamp;
    const chain: Array<Error | UnError> = error.getErrorChain();
    const formatted: string = error.format();
  }
}

// 類型注解
const options: FormatOptions = {
  includeStack: true,
  includeCause: true,
  indent: 2
};

const error: UnError = new UnError('Test');
const serialized: SerializedError = error.toJSON();

性能優(yōu)化

UnError 在設(shè)計時充分考慮了性能:

  1. 輕量級:核心代碼不到 500 行(未壓縮,且包含注釋,注釋包含示例)
  2. 零依賴:不引入任何第三方庫
  3. 按需計算:堆棧解析、格式化等操作只在調(diào)用時執(zhí)行
  4. 高效序列化:使用原生 JSON 序列化,性能優(yōu)異

測試覆蓋

UnError 擁有完善的測試體系:

# 運行測試
npm test

# 查看覆蓋率
npm run test:coverage

測試統(tǒng)計:

  • ? 62 個單元測試
  • ? 97.36% 代碼覆蓋率
  • ? 100% 函數(shù)覆蓋率
  • ? 87.5% 分支覆蓋率

運行示例

項目包含 7 個完整的示例,展示各種使用場景:

# 運行所有示例
npm run examples

# 運行單個示例
npm run example examples/01-basic-usage.ts      # 基本用法
npm run example examples/02-error-chain.ts      # 錯誤鏈
npm run example examples/03-serialization.ts    # 序列化
npm run example examples/04-formatting.ts       # 格式化
npm run example examples/05-stack-parsing.ts    # 堆棧解析
npm run example examples/06-real-world.ts       # 真實場景
npm run example examples/07-prototype-demo.ts   # 原型鏈演示

總結(jié) 

到此這篇關(guān)于UnError如何讓JavaScript錯誤處理更優(yōu)雅的文章就介紹到這了,更多相關(guān)JS錯誤處理UnError內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

芜湖县| 定兴县| 辽宁省| 原平市| 河池市| 开鲁县| 永清县| 威信县| 宁南县| 威信县| 林周县| 灵川县| 乐平市| 勐海县| 苏尼特右旗| 北碚区| 南昌县| 玉树县| 聊城市| 三都| 光山县| 华宁县| 北流市| 乌兰察布市| 东明县| 中牟县| 东安县| 南宁市| 碌曲县| 集安市| 徐汇区| 孝义市| 武邑县| 通辽市| 科尔| 西城区| 肥东县| 潞城市| 于田县| 东兴市| 襄城县|