Skip to content

Xử lý lỗi (Error Handling)

Giới thiệu (Introduction)

Laravel đã cấu hình xử lý lỗi và exceptions sẵn. Tất cả exceptions ứng dụng ném ra đều được logged và rendered cho user.

Cấu hình (Configuration)

Option debug trong config/app.php (hoặc biến .env APP_DEBUG) quyết định hiển thị chi tiết lỗi:

  • Development: đặt APP_DEBUG=true để xem chi tiết lỗi
  • Production: đặt APP_DEBUG=false để ẩn chi tiết

Xử lý Exceptions (Handling Exceptions)

Báo cáo Exceptions (Reporting Exceptions)

Mỗi exception được báo cáo (logged). Mặc định, log dựa trên cấu hình logging.

Tùy chỉnh trong bootstrap/app.php:

php
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->report(function (InvalidOrderException $e) {
        // Xử lý exception...
    });
})

Global Log Context

Thêm context cho mọi log message:

php
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->context(fn () => [
        'user_id' => auth()->id(),
    ]);
})

Exception Log Levels

Ghi exceptions ở log level cụ thể:

php
use PDOException;
use Psr\Log\LogLevel;

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->level(PDOException::class, LogLevel::CRITICAL);
})

Bỏ qua Exceptions theo loại

php
use Illuminate\Http\Client\ConnectionException;

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->dontReport([
        ConnectionException::class,
    ]);
})

Thuộc tính $dontReport trong Exception class

php
<?php

namespace App\Exceptions;

use Exception;

class InvalidOrderException extends Exception
{
    protected $dontReport = true;
}

Render Exceptions

Tùy chỉnh cách render exception thành HTTP response:

php
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (InvalidOrderException $e, Request $request) {
        return response()->view('errors.invalid-order', status: 500);
    });
})

Render cho API requests

php
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (InvalidOrderException $e, Request $request) {
        if ($request->is('api/*')) {
            return response()->json([
                'message' => 'Đơn hàng không hợp lệ.',
            ], 500);
        }
    });
})

Reportable và Renderable Exceptions

Tạo exception class với methods reportrender:

php
<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Http\Request;
use Illuminate\Http\Response;

class InvalidOrderException extends Exception
{
    /**
     * Báo cáo exception.
     */
    public function report(): void
    {
        // Gửi đến service bên ngoài...
    }

    /**
     * Render exception thành HTTP response.
     */
    public function render(Request $request): Response
    {
        return response('Đơn hàng không hợp lệ.', 500);
    }
}

Throttling Reported Exceptions

Giới hạn số lượng exceptions được báo cáo:

php
use Illuminate\Cache\RateLimiting\Limit;
use Throwable;

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->throttle(function (Throwable $e) {
        return Limit::perMinute(300);
    });
})

Throttle theo loại exception:

php
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->throttle(function (Throwable $e) {
        if ($e instanceof ApiMonitoringException) {
            return Limit::perMinute(1)->by($e->getCode());
        }
    });
})

HTTP Exceptions

Phát sinh HTTP error responses:

php
abort(404);
abort(403, 'Hành động không được phép.');
abort_unless(condition, 403);
abort_if(condition, 403);

Trang lỗi HTTP tùy chỉnh (Custom HTTP Error Pages)

Tạo view cho status code cụ thể:

resources/views/errors/404.blade.php
resources/views/errors/500.blade.php

Hoặc publish error views của Laravel:

bash
php artisan vendor:publish --tag=laravel-errors

Fallback HTTP Error Pages

Tạo trang lỗi cho một loạt status codes:

resources/views/errors/4xx.blade.php   → cho tất cả 4xx errors
resources/views/errors/5xx.blade.php   → cho tất cả 5xx errors

Biến $exception có sẵn trong view:

blade
<h2>{{ $exception->getMessage() }}</h2>