Skip to content

ADR-002: エラーハンドリング・ログ出力の統一化 #18

Description

@hiragram

ADR-002: エラーハンドリング・ログ出力の統一化

Status

Proposed

Context

コードレビューにおいて、エラーハンドリングとログ出力の一貫性に関する以下の問題が特定された:

  1. エラーハンドリングの不一致: 複数のエラーハンドリングパターンが混在

    • add.js: 古いパターン(直接console.error + process.exit)
    • install.js: 新しいCommandErrorクラス使用
    • remove.js, list.js: 混在したパターン
  2. ログ出力の不一致: ログ出力方法が統一されていない

    • install.js: 専用ログ関数(logError, logSuccess)使用
    • その他: 直接的なconsole.log使用
  3. エラー分類の不統一: エラーの種類や重要度の分類が未整備

    • ファイルシステムエラー、設定エラー、ネットワークエラーなどの区別が不明確

これらの問題により、ユーザーエクスペリエンスの一貫性が損なわれ、デバッグ時の問題特定が困難になっている。

Decision

エラーハンドリングとログ出力を統一するため、以下の方針で整備する:

1. 統一されたログシステムの構築

  • src/utils/logger.js: 包括的なログ機能
  • ログレベル制御(ERROR, WARN, INFO, DEBUG)
  • 環境変数による実行時制御
  • カラー出力とフォーマット統一

2. エラー分類の体系化

  • 既存CommandErrorクラスの拡張
  • 特化されたエラークラス(FileSystemError, ConfigError, NetworkError, ValidationError)
  • ユーザーフレンドリーなエラーメッセージ

3. 統一されたエラーハンドリングパターン

  • 全コマンドでの統一されたエラー処理
  • 適切な終了コードの設定
  • 解決策の提示機能

機能要件

FR1: エラーハンドリングの統一化

  • 目的: 全コマンドでCommandErrorクラスベースの統一されたエラーハンドリング
  • 対象: add.js, remove.js, list.js, update.js
  • 制約: 既存のエラーメッセージ形式との互換性を維持

FR2: ログ出力の統一化

  • 目的: 専用ログ関数による一貫したログ出力
  • 機能: logSuccess, logError, logInfo, logDebug
  • 制約: 既存の出力形式との互換性を維持

FR3: エラー分類の体系化

  • 目的: エラーの種類と重要度の明確な分類
  • 分類: FileSystemError, ConfigError, NetworkError, ValidationError
  • 機能: エラーコンテキストの保持と適切な表示

FR4: ログレベル制御

  • 目的: 実行時にログ出力レベルを制御可能にする
  • 制御: CCCSC_LOG_LEVEL環境変数
  • レベル: ERROR, WARN, INFO, DEBUG

FR5: ユーザーフレンドリーなエラー表示

  • 目的: 明確で実用的なエラーメッセージの提供
  • 機能: 問題の説明、解決策の提示、適切な視覚的表現

基本設計

モジュール構成

logger.js (新規)
├── エラー出力統合
├── 各コマンドファイル (統一されたログ)
└── error-types.js (拡張)
    └── command-error.js (既存)

エラーハンドリング階層

BaseError (CommandError)
├── FileSystemError
├── ConfigError  
├── NetworkError
└── ValidationError

ログレベル体系

ERROR (0) ← WARN (1) ← INFO (2) ← DEBUG (3)

詳細設計

技術選定

  • JavaScript (ES6+): 既存コードベースとの統一
  • chalk: カラー出力(既存依存関係活用)
  • 環境変数: ログレベル制御(CCCSC_LOG_LEVEL)

インターフェース設計

Logger機能

// 基本ログ関数
logError(message)   // ❌ エラーメッセージ
logWarn(message)    // ⚠️  警告メッセージ  
logInfo(message)    // ℹ️  情報メッセージ
logSuccess(message) // ✅ 成功メッセージ
logDebug(message)   // 🐛 デバッグメッセージ

エラークラス拡張

// 特化されたエラークラス
new FileSystemError(message, filePath)
new ConfigError(message, configType)
new NetworkError(message, url, statusCode)
new ValidationError(message, field, value)

// エラーハンドリングヘルパー
handleError(error, exitCode)
createUserFriendlyError(error, context)

ユニットテスト方針

  • ログレベルフィルタリングのテスト
  • メッセージフォーマットのテスト(カラー、絵文字)
  • エラークラス継承の適切な動作テスト
  • エラーハンドリングヘルパー関数のテスト
  • 環境変数による制御のテスト

移行計画

  1. Phase 1: ログ機能の実装とテスト
  2. Phase 2: エラー分類の拡張
  3. Phase 3: add.js, remove.jsの移行
  4. Phase 4: list.js, update.jsの移行
  5. Phase 5: 既存テストの更新

Consequences

正の影響

  • ユーザーエクスペリエンス向上: 一貫したエラーメッセージとログ出力
  • デバッグ効率向上: 構造化されたエラー情報とログレベル制御
  • 保守性向上: 統一されたエラーハンドリングパターン
  • 可視性向上: カラー出力と絵文字による視覚的な改善

負の影響

  • 初期実装コスト: 新しいログシステムの実装と既存コードの移行
  • 学習コスト: 開発者が新しいエラーハンドリングパターンを習得
  • 軽微な出力変更: 既存のログ出力形式の変更

リスク

  • 移行時の互換性: 既存のエラーメッセージ形式との一貫性(テストで検証)
  • パフォーマンス影響: ログ処理のオーバーヘッド(軽微、設定可能)
  • 依存関係: chalk依存の追加(既存使用済み)

緩和策

  • 段階的移行による影響最小化
  • 包括的なテストによる互換性保証
  • 環境変数による柔軟な制御機能
  • 既存出力形式との互換性維持

実装チェックリスト

  • src/utils/logger.jsの実装
  • src/utils/error-types.jsの拡張
  • src/types/index.d.tsの型定義追加
  • tests/utils/logger.test.jsの実装
  • tests/utils/error-types.test.jsの更新
  • add.jsのエラーハンドリング移行
  • remove.jsのエラーハンドリング移行
  • list.jsのエラーハンドリング移行
  • update.jsのエラーハンドリング移行
  • 既存テストの更新
  • 環境変数制御の動作確認
  • カラー出力の動作確認
  • エラーメッセージ互換性の確認

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions