CI4 Playground v4.7.3
한국어문서
예외 시나리오 실행
PageNotFoundException 시나리오는 CI4의 실제 404 에러 페이지로 이동합니다. 브라우저 뒤로가기로 돌아오세요.
PageNotFoundException — 404 처리

CI4는 PageNotFoundException을 던지면 자동으로 404 응답을 반환합니다. 컨트롤러에서 리소스를 찾지 못할 때 사용합니다.

use CodeIgniter\Exceptions\PageNotFoundException;

public function show(int $id): string
{
    $post = $this->model->find($id);

    if (! $post) {
        // 자동으로 404 응답 + app/Views/errors/html/error_404.php 렌더링
        throw PageNotFoundException::forPageNotFound();
    }

    return view('post/show', ['post' => $post]);
}
커스텀 404 뷰 — app/Views/errors/html/error_404.php
<!-- 이 파일을 만들면 CI4 기본 404 페이지 대신 사용됨 -->
<?php $message ??= '페이지를 찾을 수 없습니다.'; ?>
<h1>404 Not Found</h1>
<p><?= esc($message) ?></p>
커스텀 예외 클래스 + try/catch
// app/Exceptions/InsufficientBalanceException.php
namespace App\Exceptions;

class InsufficientBalanceException extends \RuntimeException
{
    public function __construct(int $required, int $available)
    {
        parent::__construct(
            "잔액 부족: 필요={$required}, 보유={$available}",
            402
        );
    }
}
서비스에서 던지고 컨트롤러에서 잡기
// Service
public function transfer(int $from, int $to, int $amount): void
{
    $account = $this->model->find($from);
    if ($account->balance < $amount) {
        throw new InsufficientBalanceException($amount, $account->balance);
    }
    // ... 이체 처리
}

// Controller
try {
    $this->transferService->transfer($fromId, $toId, $amount);
    return redirect()->back()->with('success', '이체 완료');

} catch (InsufficientBalanceException $e) {
    // 도메인 오류 → 사용자에게 안내
    return redirect()->back()->with('error', $e->getMessage());

} catch (\Exception $e) {
    // 예상치 못한 오류 → 로그 + 일반 메시지
    log_message('error', $e->getMessage());
    return redirect()->back()->with('error', '처리 중 오류가 발생했습니다.');
}
글로벌 예외 핸들러 — app/Config/Exceptions.php

잡히지 않은 예외를 전역에서 처리하려면 app/Config/Exceptions.php에서 handler()를 오버라이드합니다.

// app/Config/Exceptions.php
namespace Config;

use CodeIgniter\Config\Exceptions as BaseExceptions;
use CodeIgniter\Exceptions\PageNotFoundException;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Throwable;

class Exceptions extends BaseExceptions
{
    public function handler(int $statusCode, Throwable $exception,
                            RequestInterface $request,
                            ResponseInterface $response): ResponseInterface
    {
        // 404: 커스텀 응답
        if ($exception instanceof PageNotFoundException) {
            return $response->setStatusCode(404)
                ->setBody(view('errors/custom_404'));
        }

        // 운영 환경: 상세 오류 숨기고 로그만
        if (ENVIRONMENT === 'production') {
            log_message('critical', $exception->getMessage());
            return $response->setStatusCode(500)
                ->setBody(view('errors/custom_500'));
        }

        // 개발 환경: 기본 처리 위임
        return parent::handler($statusCode, $exception, $request, $response);
    }
}
운영/개발 환경 분리 팁
ENVIRONMENT === 'production' 조건으로 운영에서는 스택 트레이스를 감추고, 개발에서는 상세 오류를 표시하도록 분기하세요.