Skip to content

Latest commit

 

History

History
322 lines (247 loc) · 8.73 KB

File metadata and controls

322 lines (247 loc) · 8.73 KB

Custom Exception 다국어 처리

이 문서는 G7에서 Custom Exception 클래스의 다국어 처리 방법을 설명합니다.


TL;DR (5초 요약)

1. 예외 메시지 하드코딩 금지 → __() 함수 필수
2. 메시지 위치: lang/ko/exceptions.php, lang/en/exceptions.php
3. 파라미터 치환: __('exceptions.key', ['param' => $value])
4. 코어 예외: exceptions.template_engine.* 형식
5. 모듈 예외: vendor-module::exceptions.* 형식

목차

  1. 핵심 원칙
  2. 다국어 파일 위치 및 구조
  3. 파라미터 치환 패턴
  4. 템플릿 엔진 Custom Exception 예시
  5. Custom Exception 개발 체크리스트
  6. 관련 문서

핵심 원칙

필수: __() 함수 사용 (예외 메시지 하드코딩 금지)
필수: __() 함수를 사용한 다국어 처리

필수 규칙

  • 모든 예외 메시지는 다국어 파일에 정의: /lang/ko/exceptions.php, /lang/en/exceptions.php
  • Exception 생성자에서 __() 함수 사용: 하드코딩된 문자열 사용 금지
  • 파라미터 치환 지원: :trace, :max, :id 등의 동적 값 지원
  • 일관성 유지: 모든 커스텀 예외가 동일한 패턴 사용

다국어 파일 위치 및 구조

파일 위치

/lang/ko/exceptions.php  # 한국어 예외 메시지
/lang/en/exceptions.php  # 영어 예외 메시지

파일 구조 예시

// /lang/ko/exceptions.php
return [
    'circular_reference' => '레이아웃 순환 참조 감지: :trace',
    'max_depth_exceeded' => '레이아웃 중첩 깊이가 최대 허용 깊이(:max)를 초과했습니다.',
    'resource_not_found' => ':resource를 찾을 수 없습니다.',
];

// /lang/en/exceptions.php
return [
    'circular_reference' => 'Layout circular reference detected: :trace',
    'max_depth_exceeded' => 'Layout nesting depth exceeds maximum allowed depth (:max).',
    'resource_not_found' => ':resource not found.',
];

중첩 구조 (네임스페이스 그룹화)

// /lang/ko/exceptions.php
return [
    'template' => [
        'circular_reference' => '레이아웃 순환 참조 감지: :trace',
        'max_depth_exceeded' => '레이아웃 중첩 깊이(:current)가 최대 허용 깊이(:max)를 초과했습니다.',
        'template_not_found' => '템플릿을 찾을 수 없습니다: :identifier',
        'layout_not_found' => '레이아웃을 찾을 수 없습니다: :layout_name',
        'component_not_found' => '컴포넌트를 찾을 수 없습니다: :component_name',
        'invalid_layout_structure' => '유효하지 않은 레이아웃 구조입니다.',
    ],
];

// /lang/en/exceptions.php
return [
    'template' => [
        'circular_reference' => 'Layout circular reference detected: :trace',
        'max_depth_exceeded' => 'Layout nesting depth (:current) exceeds maximum allowed depth (:max).',
        'template_not_found' => 'Template not found: :identifier',
        'layout_not_found' => 'Layout not found: :layout_name',
        'component_not_found' => 'Component not found: :component_name',
        'invalid_layout_structure' => 'Invalid layout structure.',
    ],
];

파라미터 치환 패턴

잘못된 예시 (DON'T)

// ❌ 하드코딩된 예외 메시지 - 금지
class CircularReferenceException extends Exception
{
    public function __construct(array $stack, string $currentLayout)
    {
        $stackTrace = implode('', $stack) . "{$currentLayout}";
        $message = "레이아웃 순환 참조 감지: {$stackTrace}";  // 한국어만 지원, 다국어 불가
        parent::__construct($message);
    }
}

올바른 예시 (DO)

// ✅ 다국어 함수 사용 (파라미터 치환)
class CircularReferenceException extends Exception
{
    private array $stack;

    public function __construct(array $stack, string $currentLayout)
    {
        $this->stack = $stack;

        // ✅ 다국어 함수 사용 (파라미터 치환)
        $stackTrace = implode('', $stack) . "{$currentLayout}";
        $message = __('exceptions.circular_reference', ['trace' => $stackTrace]);

        parent::__construct($message);
    }

    public function getStack(): array
    {
        return $this->stack;
    }
}

다중 파라미터 처리

class MaxDepthExceededException extends Exception
{
    public function __construct(int $currentDepth, int $maxDepth)
    {
        // ✅ 다국어 함수 사용 (다중 파라미터)
        $message = __('exceptions.max_depth_exceeded', [
            'current' => $currentDepth,
            'max' => $maxDepth
        ]);

        parent::__construct($message);
    }
}

템플릿 엔진 Custom Exception 예시

CircularReferenceException (레이아웃 순환 참조)

템플릿 레이아웃 상속 시 순환 참조가 발생하면 이 예외를 발생시킵니다.

<?php

namespace App\Exceptions\Template;

use Exception;

/**
 * 레이아웃 순환 참조 예외
 */
class CircularReferenceException extends Exception
{
    private array $stack;

    public function __construct(array $stack, string $currentLayout)
    {
        $this->stack = $stack;

        // ✅ 다국어 함수 사용
        $stackTrace = implode('', $stack) . "{$currentLayout}";
        $message = __('exceptions.template.circular_reference', ['trace' => $stackTrace]);

        parent::__construct($message);
    }

    /**
     * 순환 참조 스택 반환
     */
    public function getStack(): array
    {
        return $this->stack;
    }
}

MaxDepthExceededException (레이아웃 깊이 초과)

레이아웃 상속 깊이가 최대 허용 깊이(10)를 초과하면 이 예외를 발생시킵니다.

<?php

namespace App\Exceptions\Template;

use Exception;

/**
 * 레이아웃 최대 깊이 초과 예외
 */
class MaxDepthExceededException extends Exception
{
    private int $currentDepth;
    private int $maxDepth;

    public function __construct(int $currentDepth, int $maxDepth = 10)
    {
        $this->currentDepth = $currentDepth;
        $this->maxDepth = $maxDepth;

        // ✅ 다국어 함수 사용 (다중 파라미터)
        $message = __('exceptions.template.max_depth_exceeded', [
            'current' => $currentDepth,
            'max' => $maxDepth
        ]);

        parent::__construct($message);
    }

    /**
     * 현재 깊이 반환
     */
    public function getCurrentDepth(): int
    {
        return $this->currentDepth;
    }

    /**
     * 최대 허용 깊이 반환
     */
    public function getMaxDepth(): int
    {
        return $this->maxDepth;
    }
}

Service에서 사용 예시 (LayoutService)

<?php

namespace App\Services\Template;

use App\Exceptions\Template\CircularReferenceException;
use App\Exceptions\Template\MaxDepthExceededException;

class LayoutService
{
    private const MAX_DEPTH = 10;

    /**
     * 레이아웃 병합 (상속 체인 처리)
     *
     * @throws CircularReferenceException 순환 참조 발생 시
     * @throws MaxDepthExceededException 깊이 초과 시
     */
    public function mergeLayouts(string $layoutName, array $stack = [], int $depth = 0): array
    {
        // 순환 참조 검사
        if (in_array($layoutName, $stack)) {
            throw new CircularReferenceException($stack, $layoutName);
        }

        // 깊이 검사
        if ($depth > self::MAX_DEPTH) {
            throw new MaxDepthExceededException($depth, self::MAX_DEPTH);
        }

        // 재귀적으로 레이아웃 병합
        // ...
    }
}

Custom Exception 개발 체크리스트

새로운 Custom Exception을 개발할 때 다음 항목을 확인하세요:

  • /lang/ko/exceptions.php에 한국어 메시지 추가
  • /lang/en/exceptions.php에 영어 메시지 추가
  • Exception 생성자에서 모든 메시지는 __() 함수 사용
  • 동적 값은 파라미터 배열로 전달 (예: ['trace' => $stackTrace])
  • 두 언어 모두에서 테스트 수행
  • 예외 메시지가 사용자에게 노출될 경우 보안 정보 포함 금지

새 Exception 추가 절차

  1. 다국어 키 정의: 적절한 네임스페이스로 그룹화
  2. Exception 클래스 생성: __() 함수로 메시지 생성
  3. 필요한 속성 저장: 디버깅이나 로깅에 필요한 값 보관
  4. getter 메서드 제공: 저장된 속성에 접근할 수 있도록 제공
  5. 테스트 작성: 두 언어 환경에서 메시지 확인

관련 문서