コンテンツにスキップ

例外処理とログ記録の改善完了レポート

[!NOTE] 最新の実装状況は 機能実装ステータス (Remaining Functionality) を参照してください。

実施内容

✅ 1. カスタム例外クラスの導入

ファイル: exceptions.py

実装した例外階層

EvoSpikeNetError (基底クラス)
├── ConfigurationError
│   ├── InvalidConfigError
│   └── MissingConfigError
├── ModelError
│   ├── ModelNotFoundError
│   ├── ModelLoadError
│   ├── ModelSaveError
│   ├── InvalidModelStateError
│   └── IncompatibleModelError
├── DataError
│   ├── DataLoadError
│   ├── DataValidationError
│   ├── InvalidDataFormatError
│   └── DataNotFoundError
├── TrainingError
│   ├── TrainingInterruptedError
│   ├── ConvergenceError
│   └── GradientError
├── CommunicationError
│   ├── ZenohError
│   ├── NodeConnectionError
│   ├── SynchronizationError
│   └── TimeoutError
├── ResourceError
│   ├── GPUError
│   ├── MemoryError
│   └── DiskSpaceError
├── EncodingError / DecodingError
├── PluginError
├── SecurityError
├── APIError
├── EvolutionError
├── DatabaseError
└── ValidationError

合計: 40+の特化した例外クラス

主要機能

  • 詳細情報の保持: details辞書で追加コンテキストを保存
  • 例外チェーン: fromキーワードで元の例外を保持
  • ユーティリティ: reraise_with_context()で例外の再送出をサポート

✅ 2. ログ記録ユーティリティの導入

ファイル: logging_utils.py

実装した機能

  1. StructuredFormatter: JSON形式の構造化ログ
  2. ColoredFormatter: 色付きコンソール出力
  3. setup_logger(): ロガーの一括設定
  4. get_logger(): ロガーの取得
  5. LogContext: コンテキスト情報の追加
  6. log_exception(): 例外の詳細なログ記録
  7. log_performance(): パフォーマンスメトリクスの記録

使用例

<!-- from evospikenet.logging_utils import get_logger, log_exception -->
<!-- TODO: update or remove - import failModelLoadError -->

logger = get_logger(__name__)

try:
    model = load_model(path)
except FileNotFoundError as e:
    raise ModelLoadError(
        f"Model file not found: {path}",
        details={"path": path}
    ) from e

✅ 3. 既存コードの修正

修正したファイル: - api_gateway.py - except:except (ValueError, TypeError)

  • models.py
  • デストラクタのexcept:にログ記録追加

  • security.py

  • except:にログ記録と特定例外型

  • compression.py

  • _deserialize_data()の多段fallbackを特定例外型に変更
  • 各ステップでログ記録を追加

  • sdk.py

  • JSON解析のexcept:except (ValueError, AttributeError)に変更

✅ 4. パッケージ初期化の更新

ファイル: __init__.py

# 最初にexceptionsとlogging_utilsをインポート
from . import exceptions
from .exceptions import (
    EvoSpikeNetError,
    ConfigurationError,
    ModelError,
    DataError,
    TrainingError,
    CommunicationError,
)

from . import logging_utils
from .logging_utils import get_logger, setup_logger, log_exception

✅ 5. CI/CD統合

ファイル: ci.yml

- name: Check exception handling
  run: |
    python scripts/check_exceptions.py
  continue-on-error: true

✅ 6. チェックスクリプトの作成

ファイル: check_exceptions.py

  • Bare except(except:)の検出
  • 広範なexcept Exception:の検出
  • 許可されるパターン(__del__cleanup)の識別

✅ 7. ベストプラクティスガイド

ファイル: docs/EXCEPTION_HANDLING_GUIDE.md

10のベストプラクティスを網羅: 1. カスタム例外の使用 2. Bare Exceptの回避 3. 例外チェーンの使用 4. ログ記録の統一 5. コンテキストマネージャー 6. 例外の再送出 7. 複数の例外型のハンドリング 8. バリデーションでのアーリーリターン 9. 非同期コードでの例外処理 10. デコレーターを使った共通エラーハンドリング

検出された残存問題

チェックスクリプトの実行結果:

❌ Found 46 issues:
   - Bare excepts: ~18件
   - Broad exceptions: ~28件

主な箇所: - evospikenet/compression.py - 複数のbare except - evospikenet/rag_milvus.py - 広範なException catch - evospikenet/attention.py - 広範なException catch - その他多数のファイル

今後の改善計画

短期(即実行推奨)

  • [ ] 残りのbare exceptを特定の例外型に置き換え
  • [ ] 広範なexcept Exceptionを具体的な例外リストに変更
  • [ ] 全てのcatchブロックにログ記録を追加

中期(今後1-2週間)

  • [ ] カスタム例外を実際のコードで使用開始
  • [ ] ログ記録を構造化フォーマットに統一
  • [ ] 例外処理のユニットテストを追加

長期(今後1ヶ月)

  • [ ] 全モジュールでベストプラクティスを適用
  • [ ] パフォーマンスログの統合
  • [ ] 分散エラー追跡システムの導入検討

利点

1. デバッグの改善

  • 特定の例外型により、エラーの原因が明確に
  • スタックトレースと詳細情報で問題解決が迅速化

2. エラーハンドリングの向上

  • 予期されるエラーと予期しないエラーを区別
  • 適切なリカバリー戦略の実装が容易

3. 保守性の向上

  • 統一されたログフォーマット
  • コードの意図が明確に

4. 本番環境の安定性

  • KeyboardInterruptやSystemExitの誤捕捉を防止
  • 適切なエラー伝播

使用ガイド

カスタム例外の使用

<!-- モジュール 'evospikenet' が見つかりませんパッケージ内の移動/名前変更を確認してください -->
<!-
try:
  import inspect
  load_kwargs = {"map_location": "cpu"}
  try:
    sig = inspect.signature(torch.load)
    if "weights_only" in sig.parameters:
      load_kwargs["weights_only"] = True
  except Exception:
    pass
  model = torch.load(path, **load_kwargs)
except FileNotFoundError as e:
  raise ModelLoadError(
    f"Model file not found: {path}",
    details={"path": path, "cwd": os.getcwd()}
  ) from e

ログ記録

<!-- TODO: update<!-- モジュール 'evospikenet' が見つかりませんパッケージ内の移動/名前変更を確認してください -->kenet.logging_utils import g risky_operation()
except DataValidationError as e:
    log_exception(
        logger,
        e,
        message="Validation failed",
        extra_context={"input_size": len(data)}
    )
    raise

チェックコマンド

# 例外処理の問題を検出
python scripts/check_exceptions.py

# CI/CDで自動実行
# すでに .github/workflows/ci.yml に統合済み

参考ドキュメント

  • exceptions.py - カスタム例外定義
  • logging_utils.py - ログユーティリティ
  • docs/EXCEPTION_HANDLING_GUIDE.md - ベストプラクティス
  • check_exceptions.py - チェックツール

実施日: 2026年1月10日 状態: ✅ 基盤完成(段階的な移行を継続)