مقدمه
یکی از مشکلات رایج در توسعه نرمافزار، پیدا کردن علت خطاهایی است که در محیط واقعی برنامه رخ میدهند. ممکن است یک کاربر هنگام ورود به حساب خود با خطا مواجه شود، پرداختی انجام نشود، یک درخواست API پاسخ مناسبی ندهد یا یکی از عملیاتهای پایگاه داده با مشکل روبهرو شود.
در چنین شرایطی، صرفاً دیدن یک صفحه خطا یا دریافت پیام 500 Internal Server Error اطلاعات کافی در اختیار برنامهنویس قرار نمیدهد.
اینجاست که Logging یا ثبت لاگ اهمیت پیدا میکند.
در لاراول، سیستم ثبت لاگ به شما اجازه میدهد اتفاقات مهم برنامه، پیامهای خطا و اطلاعات موردنیاز برای عیبیابی را ذخیره کنید. سپس میتوانید با مراجعه به فایلهای لاگ، متوجه شوید چه اتفاقی افتاده و مشکل از کجا ایجاد شده است.
در این مقاله یاد میگیریم:
- لاگ چیست و چه کاربردی دارد؟
- فایلهای لاگ Laravel کجا ذخیره میشوند؟
- چگونه با کلاس
Logپیام ثبت کنیم؟ - تفاوت سطوح مختلف لاگ چیست؟
- چگونه فایل لاگ روزانه بسازیم؟
- چگونه خطاهای یک عملیات را ثبت کنیم؟
- چطور اطلاعات اضافی به لاگ اضافه کنیم؟
- چه نکاتی را هنگام ثبت لاگ در محیط واقعی باید رعایت کنیم؟
مثالهای این مقاله برای Laravel 12 و نسخههای جدید لاراول قابل استفادهاند؛ تنظیمات جزئی ممکن است با توجه به نسخه پروژه متفاوت باشند.
۱. لاگ چیست و چه کاربردی دارد؟
لاگ، گزارشی از اتفاقات مهمی است که هنگام اجرای برنامه رخ میدهند.
برای مثال، فرض کنید کاربری وارد سایت شما میشود. میتوانید اتفاقات زیر را ثبت کنید:
- درخواست ورود کاربر دریافت شد.
- احراز هویت کاربر با موفقیت انجام شد.
- درخواست ارتباط با یک سرویس خارجی ارسال شد.
- ارتباط با سرویس خارجی ناموفق بود.
- هنگام ذخیره اطلاعات در پایگاه داده خطایی رخ داد.
این اطلاعات به شما کمک میکنند رفتار برنامه را بررسی کنید، بدون اینکه لازم باشد هر بار خطا را مستقیماً روی سیستم کاربر بازسازی کنید.
البته لاگ جایگزین Debug یا تستنویسی نیست. هرکدام کاربرد خاص خودشان را دارند:
- Debug: برای بررسی مرحلهبهمرحله مشکل و پیدا کردن علت آن.
- Logging: برای نگهداری گزارش اتفاقات برنامه و بررسی آنها در آینده.
- Testing: برای اطمینان از اینکه بخشهای برنامه مطابق انتظار کار میکنند.
۲. فایلهای لاگ در Laravel کجا قرار دارند؟
در یک پروژه استاندارد لاراول، فایلهای لاگ معمولاً در مسیر زیر قرار میگیرند:
storage/logs/
اگر کانال پیشفرض پروژه از نوع single باشد، فایل اصلی لاگ معمولاً این است:
storage/logs/laravel.log
برای مثال، ساختار بخشی از پروژه به این صورت خواهد بود:
my-project/
├── app/
├── bootstrap/
├── config/
├── routes/
├── storage/
│ └── logs/
│ └── laravel.log
├── .env
└── artisan
هر زمان پیامی با موفقیت در این کانال ثبت شود، میتوانید آن را در فایل مربوطه مشاهده کنید.
نکته مهم: در بعضی پروژهها، تنظیمات لاگ تغییر داده شدهاند یا برنامه از کانال دیگری استفاده میکند. بنابراین همیشه مسیر فایل را با توجه به تنظیمات پروژه بررسی کنید.
۳. آشنایی با کلاس Log در لاراول
لاراول یک Facade با نام Log در اختیار ما قرار میدهد که برای ثبت پیامها استفاده میشود.
برای استفاده از آن، کلاس زیر را در فایل PHP خود وارد کنید:
use Illuminate\Support\Facades\Log;
حالا میتوانید یک پیام ساده ثبت کنید:
Log::info('Application started successfully.');
این دستور یک پیام با سطح info ثبت میکند.
برای مثال، میتوانید آن را در یک کنترلر قرار دهید:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Log;
class HomeController extends Controller
{
public function index()
{
Log::info('Home page visited.');
return view('home');
}
}
هر بار که متد index اجرا شود، پیام موردنظر در کانال لاگ پیشفرض ثبت خواهد شد.
این مثال صرفاً برای آشنایی با نحوه استفاده از Log است. در یک پروژه واقعی، بهتر است برای ثبت بازدیدهای پرتعداد، از لاگنویسی بیشازحد خودداری کنید.
۴. آشنایی با سطوح مختلف لاگ در Laravel
همه پیامها اهمیت یکسانی ندارند. برای مثال، ثبت یک پیام ساده درباره اجرای یک عملیات با ثبت خطای توقف کامل سیستم متفاوت است.
لاراول از سطوح استاندارد لاگ استفاده میکند که از شدت کمتر به بیشتر عبارتاند از:
| سطح لاگ | کاربرد |
|---|---|
debug | جزئیات فنی برای عیبیابی |
info | اطلاعات عادی درباره روند اجرای برنامه |
notice | اتفاق قابلتوجه، اما نه لزوماً نگرانکننده |
warning | شرایط غیرعادی که لزوماً اجرای برنامه را متوقف نمیکنند |
error | خطا در انجام یک عملیات |
critical | خطای جدی که ممکن است بخش مهمی از سیستم را مختل کند |
alert | وضعیت بسیار جدی که نیازمند اقدام سریع است |
emergency | وضعیت بحرانی، مانند از دسترس خارج شدن کل سیستم |
برای استفاده از این سطوح، میتوانید متد مناسب را فراخوانی کنید:
use Illuminate\Support\Facades\Log;
Log::debug('Debug information.');
Log::info('User profile opened.');
Log::notice('An unusual event occurred.');
Log::warning('External service response is slow.');
Log::error('Payment request failed.');
Log::critical('Critical service failure.');
Log::alert('Immediate intervention is required.');
Log::emergency('The application is unavailable.');
این پیامها صرفاً نمونهاند. در پروژه خودتان باید سطحی را انتخاب کنید که واقعاً با اهمیت رویداد مطابقت داشته باشد.
آیا همه پیامهای لاگ ذخیره میشوند؟
خیر. سطح تنظیمشده برای کانال مشخص میکند که چه پیامهایی ثبت شوند.
برای مثال، اگر حداقل سطح کانال error باشد، پیامهای debug و info معمولاً در آن کانال ثبت نمیشوند؛ اما پیامهای error و سطوح جدیتر ثبت خواهند شد.
این تنظیم کمک میکند در محیط واقعی، حجم لاگها بیشازحد افزایش پیدا نکند.
۵. ثبت اطلاعات تکمیلی در لاگ
گاهی پیام ساده کافی نیست. فرض کنید درخواست پرداخت یک کاربر ناموفق بوده است. بهتر است علاوه بر توضیح خطا، شناسه سفارش یا اطلاعات غیرحساس مرتبط با آن را نیز ثبت کنید.
لاراول امکان ارسال یک آرایه از اطلاعات تکمیلی را فراهم میکند:
use Illuminate\Support\Facades\Log;
Log::error('Payment request failed.', [
'order_id' => 1250,
'gateway' => 'example',
'status' => 'failed',
]);
در این مثال، پیام خطا همراه با اطلاعات سفارش و درگاه ثبت میشود.
این روش برای بررسی مشکلات پیچیده بسیار مفید است؛ زیرا میتوانید مشخص کنید خطا مربوط به کدام عملیات بوده است.
استفاده از مقادیر پویا
فرض کنید یک مدل Order دارید و میخواهید خطای مربوط به سفارش مشخصی را ثبت کنید:
Log::warning('Order processing requires investigation.', [
'order_id' => $order->id,
'user_id' => $order->user_id,
]);
با این روش، هنگام بررسی لاگ میتوانید سفارش مربوطه را پیدا کنید.
نکته امنیتی: رمز عبور، توکن احراز هویت، کلید API، اطلاعات کامل کارت بانکی و سایر دادههای حساس را در لاگ ذخیره نکنید. همچنین در صورت استفاده از ایمیل، شماره تلفن یا شناسه کاربران، سیاست حفظ حریم خصوصی پروژه را در نظر بگیرید.
۶. تنظیم کانال ثبت لاگ در Laravel
لاراول از مفهومی به نام Channel برای مشخص کردن محل و روش ذخیره لاگها استفاده میکند.
تنظیمات اصلی این سیستم در فایل زیر قرار دارند:
config/logging.php
در این فایل، میتوانید کانال پیشفرض، مسیر ذخیرهسازی، سطح لاگ و روش نگهداری فایلها را تنظیم کنید.
مقدار کانال پیشفرض معمولاً از متغیر LOG_CHANNEL در فایل .env خوانده میشود.
برای مثال:
LOG_CHANNEL=stack
LOG_LEVEL=debug
در بسیاری از پروژهها، کانال stack بهعنوان یک مجموعه از کانالهای دیگر استفاده میشود. تنظیمات واقعی آن به فایل config/logging.php بستگی دارد.
اگر مقدار LOG_LEVEL را روی debug قرار دهید، در صورت سازگاری تنظیمات کانال، پیامهای جزئیتر نیز امکان ثبت خواهند داشت.
انواع رایج کانالها
| کانال | توضیح |
|---|---|
single | ذخیره پیامها در یک فایل |
daily | ایجاد فایلهای جداگانه برای روزهای مختلف |
stack | ترکیب چند کانال |
slack | ارسال پیام به Slack با تنظیمات مناسب |
errorlog | استفاده از سیستم ثبت خطای PHP یا محیط اجرا |
syslog | ارسال لاگ به سیستم Syslog |
همه این کانالها الزاماً برای هر پروژه فعال یا تنظیمشده نیستند. برای استفاده از کانالهایی مانند Slack، باید اطلاعات موردنیاز آن را نیز پیکربندی کنید.
۷. چگونه فایل لاگ روزانه بسازیم؟
در پروژههای واقعی، فایل لاگ ممکن است بهمرور بسیار بزرگ شود. یکی از راهکارهای متداول، استفاده از کانال daily است.
در فایل .env میتوانید تنظیمات مشابه زیر داشته باشید:
LOG_CHANNEL=daily
LOG_LEVEL=debug
LOG_DAILY_DAYS=14
در پیکربندی استاندارد Laravel، کانال daily میتواند برای روزهای مختلف فایل جداگانه ایجاد کند و تعداد روزهای نگهداری را با تنظیم مربوطه کنترل کند.
برای نمونه، ممکن است فایلهایی با نامهای مشابه زیر داشته باشید:
storage/logs/laravel-2026-10-16.log
storage/logs/laravel-2026-10-17.log
storage/logs/laravel-2026-10-18.log
نام دقیق فایلها به تنظیمات کانال بستگی دارد.
متغیر LOG_DAILY_DAYS در پیکربندی استاندارد، تعداد روزهای نگهداری فایلهای چرخشی را مشخص میکند. با این حال، باید مطمئن شوید که کانال daily در config/logging.php به همین متغیر متصل شده است.
اگر پس از تغییر فایل .env همچنان تنظیمات قبلی اعمال میشوند، در محیط توسعه میتوانید کش تنظیمات را پاک کنید:
php artisan config:clear
در محیط عملیاتی، پیش از اجرای دستورات پاکسازی کش، فرایند استقرار پروژه و نحوه مدیریت تنظیمات را در نظر بگیرید.
۸. ثبت خطا با استفاده از try و catch
یکی از کاربردهای مهم لاگ، ثبت خطاهایی است که هنگام اجرای یک عملیات رخ میدهند.
فرض کنید برنامه شما برای دریافت اطلاعات با یک سرویس خارجی ارتباط برقرار میکند. ممکن است ارتباط با سرویس به دلیل قطعی شبکه یا پاسخ نامعتبر با مشکل مواجه شود.
میتوانید از try و catch برای مدیریت خطا استفاده کنید:
use Illuminate\Support\Facades\Log;
use Throwable;
try {
// اجرای عملیات موردنظر
$result = performOperation();
} catch (Throwable $e) {
Log::error('Operation failed.', [
'message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
]);
throw $e;
}
در این مثال، فرض شده است که تابع performOperation() از قبل در پروژه تعریف شده است؛ این تابع بخشی از توابع پیشفرض لاراول نیست.
اگر عملیات خطا ایجاد کند، اطلاعات مربوط به خطا ثبت میشود و سپس با throw $e همان خطا دوباره پرتاب میشود تا مدیریت بالادستی برنامه بتواند آن را پردازش کند.
چرا خطا را دوباره پرتاب میکنیم؟
گاهی ثبت خطا بهتنهایی کافی نیست. اگر پس از وقوع خطا، اجرای برنامه بدون توجه به شکست عملیات ادامه پیدا کند، ممکن است نتیجه نامعتبر به کاربر برگردانده شود.
در مثال بالا، خطا ثبت میشود، اما پنهان نمیماند.
البته در بعضی شرایط لازم است بهجای پرتاب مجدد خطا، یک پاسخ مشخص به کاربر برگردانید یا عملیات جایگزین انجام دهید. انتخاب روش صحیح به منطق کسبوکار پروژه بستگی دارد.
نکته مهم درباره مدیریت استثناها
لازم نیست تمام کدهای برنامه را داخل try/catch قرار دهید. لاراول سازوکار مدیریت استثناهای خودش را دارد و بسیاری از خطاهای مدیریتنشده را بهصورت خودکار پردازش میکند.
بهتر است زمانی از try/catch استفاده کنید که میخواهید خطا را به شکل مشخصی مدیریت کنید، اطلاعات تکمیلی ثبت کنید یا رفتار خاصی برای شکست عملیات در نظر بگیرید.
۹. استفاده از Log در کنترلر برای عیبیابی
برای درک بهتر کاربرد عملی لاگ، یک مثال در کنترلر بررسی میکنیم.
فرض کنید متدی برای نمایش اطلاعات یک محصول دارید:
<?php
namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Support\Facades\Log;
class ProductController extends Controller
{
public function show(int $id)
{
Log::info('Product details requested.', [
'product_id' => $id,
]);
$product = Product::find($id);
if (! $product) {
Log::warning('Product not found.', [
'product_id' => $id,
]);
abort(404, 'Product not found.');
}
return view('products.show', [
'product' => $product,
]);
}
}
در این مثال سه اتفاق مهم رخ میدهد:
- درخواست نمایش محصول ثبت میشود.
- اگر محصول پیدا نشود، یک پیام هشدار همراه با شناسه محصول ثبت خواهد شد.
- در صورت پیدا نشدن محصول، پاسخ 404 برگردانده میشود.
به این ترتیب، اگر کاربران گزارش دهند که صفحه محصولی باز نمیشود، میتوانید بررسی کنید چه شناسهای درخواست شده و آیا محصول موردنظر پیدا شده است یا خیر.
البته اگر متد show در پروژه شما با findOrFail() یا Route Model Binding پیادهسازی شده باشد، باید روش ثبت لاگ را متناسب با همان ساختار تنظیم کنید.
۱۰. نوشتن لاگ در یک کانال مشخص
گاهی میخواهید پیامهای مربوط به یک بخش را از سایر پیامها جدا کنید.
برای مثال، ممکن است بخواهید لاگهای مربوط به پرداخت را در یک فایل اختصاصی نگهداری کنید.
ابتدا در آرایه channels فایل config/logging.php یک کانال تعریف کنید:
'channels' => [
// سایر کانالها
'payments' => [
'driver' => 'single',
'path' => storage_path('logs/payments.log'),
'level' => env('LOG_LEVEL', 'debug'),
'replace_placeholders' => true,
],
],
سپس در کد خود از کانال تعریفشده استفاده کنید:
use Illuminate\Support\Facades\Log;
Log::channel('payments')->info('Payment initiated.', [
'order_id' => 1250,
]);
با اجرای این کد، پیام در فایل زیر ثبت میشود:
storage/logs/payments.log
این روش برای سیستمهای بزرگ که بخشهای متعددی مانند پرداخت، سفارشها، ارتباطات API و عملیات مدیریتی دارند، مفید است.
توجه: نام کانال باید دقیقاً با نام تعریفشده در config/logging.php مطابقت داشته باشد. همچنین بهتر است پیش از استفاده از این ساختار در محیط عملیاتی، مجوز نوشتن فایلها و سیاست نگهداری لاگها را بررسی کنید.
۱۱. چگونه لاگهای Laravel را مشاهده کنیم؟
برای مشاهده لاگها چند روش ساده وجود دارد.
روش اول: بررسی فایل در File Manager
اگر به هاست از طریق کنترلپنل دسترسی دارید، وارد پوشه پروژه شوید و مسیر زیر را باز کنید:
storage/logs/
سپس فایل مربوط به کانال فعال را باز کنید.
در هاستهایی که دسترسی SSH ندارند، ممکن است این روش سادهترین راه باشد.
روش دوم: مشاهده لاگ با ترمینال
اگر از طریق SSH به سرور متصل هستید، میتوانید آخرین خطوط فایل را مشاهده کنید:
tail -n 100 storage/logs/laravel.log
برای مشاهده زنده پیامهایی که به فایل اضافه میشوند، از دستور زیر استفاده کنید:
tail -f storage/logs/laravel.log
برای خروج از حالت مشاهده زنده، معمولاً میتوانید کلیدهای Ctrl + C را فشار دهید.
اگر کانال پروژه daily باشد یا نام فایل تغییر کرده باشد، باید مسیر فایل صحیح را جایگزین کنید.
روش سوم: بررسی مجوزهای پوشه
اگر پیامها در فایل لاگ ثبت نمیشوند، یکی از مواردی که باید بررسی کنید، مجوز نوشتن در پوشه storage است.
در پروژه لاراول، کاربر سیستمعاملی که PHP را اجرا میکند باید بتواند در مسیرهای لازم، از جمله پوشههای مربوط به لاگ، بنویسد.
بهتر است مالکیت و مجوزها را مطابق تنظیمات وبسرور خود اصلاح کنید. از دادن مجوزهای بیشازحد باز، مانند 777، بدون دلیل مشخص خودداری کنید.
۱۲. تفاوت Log و dd در لاراول چیست؟
در هنگام عیبیابی، دو ابزار پرکاربرد Log و dd() هستند؛ اما عملکرد آنها متفاوت است.
| ویژگی | Log | dd() |
|---|---|---|
| هدف اصلی | ثبت اطلاعات برای بررسی بعدی | نمایش مقدار برای بررسی فوری |
| ذخیره اطلاعات | معمولاً در کانال لاگ | بهصورت پیشفرض در فایل لاگ ذخیره نمیشود |
| متوقف کردن اجرای کد | خیر | بله |
| مناسب محیط عملیاتی | با رعایت اصول امنیتی | معمولاً خیر |
| کاربرد رایج | بررسی اتفاقات برنامه در طول زمان | عیبیابی سریع در محیط توسعه |
برای مثال:
Log::info('User ID:', [
'user_id' => $user->id,
]);
این کد اطلاعات را در کانال لاگ ثبت میکند.
در مقابل:
dd($user);
مقدار متغیر را نمایش میدهد و اجرای معمول برنامه را در همان نقطه متوقف میکند.
بنابراین، اگر میخواهید اطلاعات یک خطا را پس از وقوع آن در محیط واقعی بررسی کنید، لاگ معمولاً انتخاب مناسبتری است.
۱۳. نکات مهم برای استفاده حرفهای از Logging
ثبت لاگ زمانی مفید است که اطلاعات ثبتشده قابلاستفاده، امن و قابلمدیریت باشند.
۱. پیامهای واضح بنویسید.
بهجای ثبت پیام عمومی مانند Error occurred، مشخص کنید چه عملیاتی با مشکل مواجه شده است.
Log::error('Failed to create invoice.', [
'order_id' => $orderId,
]);
۲. سطح لاگ مناسب را انتخاب کنید.
هر رویداد عادی نباید با سطح error ثبت شود. استفاده نادرست از سطوح باعث میشود پیدا کردن خطاهای واقعی دشوارتر شود.
۳. اطلاعات حساس را ثبت نکنید.
رمز عبور، توکنهای دسترسی، کلیدهای خصوصی و اطلاعات محرمانه کاربران نباید در فایل لاگ ذخیره شوند.
۴. برای فایلهای لاگ سیاست نگهداری داشته باشید.
فایلهای حجیم میتوانند فضای سرور را اشغال کنند. از کانالهای چرخشی و سیاست مناسب برای نگهداری و حذف لاگهای قدیمی استفاده کنید.
۵. در محیط تولید، سطح لاگ را متناسب تنظیم کنید.
ثبت تمام جزئیات فنی ممکن است حجم زیادی از اطلاعات تولید کند. سطح لاگ را براساس نیاز عملیاتی انتخاب کنید و مطمئن شوید پیامهای ضروری حذف نمیشوند.
۶. لاگها را در دسترس عموم قرار ندهید.
فایلهای لاگ باید خارج از مسیر عمومی وب باقی بمانند و دسترسی به آنها محدود باشد. مسیر storage/logs در ساختار معمول لاراول خارج از پوشه public قرار دارد؛ این وضعیت را با تنظیمات سرور خود نیز بررسی کنید.
۷. در عملیات حساس، شناسه قابلپیگیری ثبت کنید.
برای مثال، شناسه سفارش، شناسه درخواست یا شناسه عملیات میتواند ارتباط میان پیامهای مختلف را آسانتر کند.
۱۴. خطاهای رایج در ثبت لاگ Laravel
خطای اول: فایل لاگ ایجاد نمیشود
دلایل احتمالی عبارتاند از:
- کاربر اجرای PHP مجوز نوشتن ندارد.
- کانال یا مسیر فایل اشتباه تنظیم شده است.
- تنظیمات کششده با فایل
.envهماهنگ نیستند. - برنامه از کانالی غیر از کانال مورد انتظار استفاده میکند.
ابتدا config/logging.php، مقدار LOG_CHANNEL و مجوزهای پوشه storage را بررسی کنید.
خطای دوم: پیامهای Debug ثبت نمیشوند
اگر پیامهای debug را مشاهده نمیکنید، مقدار LOG_LEVEL و سطح کانال موردنظر را بررسی کنید. اگر حداقل سطح کانال بالاتر از debug باشد، پیامهای جزئیتر ممکن است فیلتر شوند.
خطای سوم: پس از تغییر تنظیمات، رفتار برنامه عوض نمیشود
ممکن است تنظیمات در کش قرار داشته باشند. در محیط توسعه میتوانید اجرا کنید:
php artisan config:clear
سپس مجدداً لاگها را بررسی کنید.
خطای چهارم: فایل لاگ بیش از حد بزرگ شده است
اگر همه اتفاقات برنامه را بدون محدودیت ثبت کنید، فایلها بهسرعت بزرگ میشوند. استفاده از کانال daily، تعیین مدت نگهداری و کاهش پیامهای غیرضروری میتواند به مدیریت بهتر فضای ذخیرهسازی کمک کند.
جمعبندی
سیستم Logging یکی از ابزارهای مهم برای توسعه و نگهداری برنامههای لاراول است. با استفاده از Facade مربوط به Log میتوانید پیامهای عادی، هشدارها و خطاها را ثبت کنید و در صورت بروز مشکل، اطلاعات موردنیاز برای بررسی آن را در اختیار داشته باشید.
در این مقاله یاد گرفتیم چگونه:
- پیامهای مختلف را با
Logثبت کنیم. - از سطوحی مانند
info،warningوerrorاستفاده کنیم. - اطلاعات تکمیلی را همراه پیام ذخیره کنیم.
- کانال پیشفرض و کانال اختصاصی بسازیم.
- لاگها را از فایل و ترمینال مشاهده کنیم.
- خطاها را در عملیاتهای حساس ثبت کنیم.
- امنیت و حجم فایلهای لاگ را مدیریت کنیم.
اگر میخواهید پروژه لاراول شما در محیط واقعی قابلاعتمادتر باشد، بهتر است از همان ابتدای توسعه، برای ثبت خطاهای مهم و رویدادهای کلیدی برنامه یک راهکار مشخص داشته باشید.
در مقاله بعدی از این مجموعه میتوانیم به سراغ مدیریت خطا در Laravel برویم و بررسی کنیم چگونه خطاها و استثناها را بهشکل اصولی مدیریت کنیم و پاسخ مناسبی به کاربر بدهیم.





