TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 548 subscribers
Post #160 72
مدیریت خطای سراسری در ASP.NET Core: از Middleware تا Handlerهای مدرن 🚨


بیایید در مورد چیزی صحبت کنیم که همه ما با آن سر و کار داریم اما اغلب تا آخرین لحظه به تعویق می‌اندازیم - مدیریت خطا در اپلیکیشن‌های ASP.NET Core ما.

وقتی چیزی در پروداکشن خراب می‌شود، آخرین چیزی که می‌خواهید یک خطای مبهم 500 بدون هیچ زمینه‌ای است. مدیریت خطای مناسب فقط مربوط به لاگ کردن استثناها نیست. بلکه در مورد این است که مطمئن شوید اپلیکیشن شما به آرامی شکست می‌خورد و اطلاعات مفیدی به فراخواننده (و شما) می‌دهد.

در این مقاله، گزینه‌های اصلی برای مدیریت خطای سراسری در ASP.NET Core را بررسی خواهیم کرد.

مدیریت خطای مبتنی بر Middleware 📜

روش کلاسیک برای گرفتن استثناهای کنترل‌نشده، استفاده از Middleware سفارشی است. اینجاست که اکثر ما شروع می‌کنیم، و صادقانه بگویم، هنوز هم برای اکثر سناریوها عالی کار می‌کند.
internal sealed class GlobalExceptionHandlerMiddleware(
RequestDelegate next,
ILogger<GlobalExceptionHandlerMiddleware> logger)
{
public async Task InvokeAsync(HttpContext context)
{
try
{
await next(context);
}
catch (Exception ex)
{
logger.LogError(ex, "Unhandled exception occurred");

// حتماً قبل از نوشتن در بدنه پاسخ، کد وضعیت را تنظیم کنید
context.Response.StatusCode = ex switch
{
ApplicationException => StatusCodes.Status400BadRequest,
_ => StatusCodes.Status500InternalServerError
};

await context.Response.WriteAsJsonAsync(
new ProblemDetails
{
Type = ex.GetType().Name,
Title = "An error occured",
Detail = ex.Message
});
}
}
}

فراموش نکنید که middleware را به پایپ‌لاین درخواست اضافه کنید:
app.UseMiddleware<GlobalExceptionHandlerMiddleware>();

این رویکرد محکم است و در همه جای پایپ‌لاین شما کار می‌کند. زیبایی آن در سادگی‌اش است: همه چیز را در یک try-catch بپیچید، خطا را لاگ کنید و یک پاسخ یکپارچه برگردانید.
اما وقتی شروع به افزودن قوانین خاص برای انواع مختلف استثناها می‌کنید (مانند ValidationException, NotFoundException)، این به یک آشفتگی تبدیل می‌شود.

معرفی IProblemDetailsService 📄

مایکروسافت این نقطه ضعف را تشخیص داد و IProblemDetailsService را برای استانداردسازی پاسخ‌های خطا به ما داد. به جای سریال‌سازی دستی آبجکت‌های خطای خودمان، می‌توانیم از فرمت داخلی Problem Details استفاده کنیم.
// ...
catch (Exception ex)
{
logger.LogError(ex, "Unhandled exception occurred");

context.Response.StatusCode = ex switch
{
ApplicationException => StatusCodes.Status400BadRequest,
_ => StatusCodes.Status500InternalServerError
};

await problemDetailsService.TryWriteAsync(new ProblemDetailsContext
{
HttpContext = context,
Exception = ex,
ProblemDetails = new ProblemDetails
{
Type = ex.GetType().Name,
Title = "An error occured",
Detail = ex.Message
}
});
}
// ...


این خیلی تمیزتر است. ما اکنون از یک فرمت استاندارد استفاده می‌کنیم که مصرف‌کنندگان API انتظار دارند. اما هنوز با مشکل آن switch statement در حال رشد گیر کرده‌ایم.
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →