﻿
{"id":26851,"date":"2024-01-07T22:10:22","date_gmt":"2024-01-07T22:10:22","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=26851"},"modified":"2024-01-07T22:11:34","modified_gmt":"2024-01-07T22:11:34","slug":"asp-net-core-8-global-error-handling","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-8-global-error-handling\/","title":{"rendered":"Asp.NET Core 8 &#8211; Global Error Handling"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Geli\u015ftirdi\u011fimiz uygulamalar\u0131m\u0131z\u0131 her ne kadar hassas ve g\u00fcvenilir bir \u015fekilde tasarl\u0131yor olsak da, genellikle yaz\u0131l\u0131mlar\u0131n \u00e7al\u0131\u015fma s\u00fcrecinin do\u011fal bir par\u00e7as\u0131 olan hata durumlar\u0131 ister istemez meydana gelecektirler ve \u00f6zellikle bu durumlar web uygulamalar\u0131 i\u00e7in neredeyse ka\u00e7\u0131n\u0131lmazd\u0131r diyebiliriz. Ancak, iyi bir yaz\u0131l\u0131m geli\u015ftirme s\u00fcrecinde, d\u00fczg\u00fcn test stratejileri ve hataya dayan\u0131kl\u0131 bir kod yazma yakla\u015f\u0131m\u0131 ile olas\u0131 hatalar\u0131n say\u0131s\u0131 azalt\u0131labilecek ve uygulamalar\u0131n daha sa\u011flam ve sa\u011fl\u0131kl\u0131 olmas\u0131 sa\u011flanabilecektir. Bunlar\u0131n yan\u0131nda yine de hatalar ger\u00e7e\u011fin birer par\u00e7as\u0131 oldu\u011funu hissettirecek ve elbet d\u0131\u015f d\u00fcnyadan gelen inputlardan yahut i\u015fin kalbi olan veritabanlar\u0131ndan, belki de hi\u00e7bir zaman bilemeyece\u011fimiz t\u00fcrl\u00fc fakt\u00f6rlerden kaynakl\u0131 er ya da ge\u00e7 kendilerini g\u00f6sterecektirler. \u0130\u015fte bu tarz durumlarda -biz elimizden geleni yapt\u0131k, taktir b\u00f6yleymi\u015f- demeyecek ve hatalar\u0131 kullan\u0131c\u0131lara yans\u0131tmaks\u0131z\u0131n y\u00f6netece\u011fiz. Hata durumlar\u0131na kar\u015f\u0131n farkl\u0131 davran\u0131\u015flar\u0131 devreye sokup, kullan\u0131c\u0131 a\u00e7\u0131s\u0131ndan olmas\u0131 gereken manip\u00fclasyonlar\u0131 ger\u00e7ekle\u015ftirece\u011fiz ve biryandan da, yeri gelecek trace ederek yeri gelecek loglama da bulunarak yaz\u0131l\u0131m s\u00fcrecinin risk y\u00f6netimine dair \u00f6nemli olan bu par\u00e7alar\u0131 e\u015fli\u011finde s\u00fcreci en ideal boyuta ta\u015f\u0131maya odaklanaca\u011f\u0131z.<\/p>\n<p>Bizler bu ideal boyut i\u00e7in \u00f6nceden klavyeye ald\u0131\u011f\u0131m\u0131z <a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-coreda-ki-exceptionlari-otomatik-olarak-yonetin\/\" rel=\"noopener\" target=\"_blank\">Asp.NET Core\u2019da ki Exception\u2019lar\u0131 Otomatik Olarak Y\u00f6netin<\/a> ba\u015fl\u0131kl\u0131 yaz\u0131m\u0131zda uygulayabilece\u011fimiz y\u00f6ntemlerden en elveri\u015fli olan\u0131n\u0131 incelemi\u015f ve tecr\u00fcbe etmi\u015ftik.<\/p>\n<p>Ya da alternatif olarak a\u015fa\u011f\u0131daki gibi bir middleware e\u015fli\u011finde de s\u00fcre\u00e7te al\u0131nabilecek t\u00fcm hatalara kar\u015f\u0131n bir tutum sergileyebiliriz.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class ExceptionHandlingMiddleware(ILogger&lt;ExceptionHandlingMiddleware&gt; logger, RequestDelegate next)\r\n    {\r\n        public async Task InvokeAsync(HttpContext context)\r\n        {\r\n            try\r\n            {\r\n                await next(context);\r\n            }\r\n            catch (Exception exception)\r\n            {\r\n                string errorMessage = $&quot;Bir hata olu\u015ftu. Hata mesaj\u0131 :  {exception.Message}&quot;;\r\n                logger.LogError(exception, errorMessage);\r\n\r\n                context.Response.StatusCode = StatusCodes.Status500InternalServerError;\r\n                await context.Response.WriteAsJsonAsync(new\r\n                {\r\n                    Title = &quot;Server Error&quot;,\r\n                    Status = context.Response.StatusCode,\r\n                    Message = errorMessage\r\n                });\r\n            }\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<p>Tabi bu middleware&#8217;in a\u015fa\u011f\u0131daki gibi yap\u0131land\u0131r\u0131lmas\u0131 kayd\u0131yla;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar builder = WebApplication.CreateBuilder(args);\r\n\r\nbuilder.Services.AddLogging();\r\n\r\nvar app = builder.Build();\r\n\r\napp.UseMiddleware&lt;Global.Error.Handling.Example.Traditional_Method.ExceptionHandlingMiddleware&gt;();\r\n\r\napp.MapGet(&quot;\/&quot;, () =&gt;\r\n{\r\n    throw new Exception(&quot;Laylaylom galiba sana g\u00f6re sevmeler...&quot;);\r\n});\r\n\r\napp.Run();\r\n<\/pre>\n<\/div>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere Asp.NET Core olas\u0131 hata durumlar\u0131na kar\u015f\u0131n refleks g\u00f6sterebilmemiz i\u00e7in bizlere birka\u00e7 se\u00e7enek sunmaktad\u0131r. Bu se\u00e7eneklere ek olarak Asp.NET Core 8 ile birlikte hata durumlar\u0131n\u0131 y\u00f6netebilmek i\u00e7in <code>IExceptionHandler<\/code> interface&#8217;ini sunmaktad\u0131r .<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class ExceptionHandler(ILogger&lt;ExceptionHandler&gt; logger) : IExceptionHandler\r\n    {\r\n        public async ValueTask&lt;bool&gt; TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)\r\n        {\r\n            string errorMessage = $&quot;Bir hata olu\u015ftu. Hata mesaj\u0131 :  {exception.Message}&quot;;\r\n            logger.LogError(exception, errorMessage);\r\n\r\n            httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;\r\n            await httpContext.Response.WriteAsJsonAsync(new\r\n            {\r\n                Title = &quot;Server Error&quot;,\r\n                Status = httpContext.Response.StatusCode,\r\n                Message = errorMessage\r\n            });\r\n\r\n            return true;\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<p>Bu interface, yukar\u0131daki kod blo\u011funda da g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere <code>TryHandleAsync<\/code> metodunu uygulatt\u0131rmakta ve olas\u0131 hataya kar\u015f\u0131n bir handle s\u00f6z konusuysa geriye true de\u011filse false olmak \u00fczere boolean de\u011fer d\u00f6nd\u00fcrmektedir.<\/p>\n<p>Olu\u015fturulan bu exception handler s\u0131n\u0131f\u0131n\u0131 Asp.NET Core request pipeline&#8217;\u0131na dahil edebilmek i\u00e7in a\u015fa\u011f\u0131daki gibi bir yap\u0131land\u0131rma yeterlidir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar builder = WebApplication.CreateBuilder(args);\r\n\r\nbuilder.Services.AddLogging();\r\n\r\nbuilder.Services.AddExceptionHandler&lt;Global.Error.Handling.Example.New_Method.ExceptionHandler&gt;();\r\nbuilder.Services.AddProblemDetails();\r\n\r\nvar app = builder.Build();\r\n\r\napp.UseExceptionHandler();\r\n\r\napp.MapGet(&quot;\/&quot;, () =&gt;\r\n{\r\n    throw new Exception(&quot;Laylaylom galiba sana g\u00f6re sevmeler...&quot;);\r\n});\r\n\r\napp.Run();\r\n<\/pre>\n<\/div>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere; <strong><em>5.<\/em><\/strong> sat\u0131rda oldu\u011fu gibi <code>AddExceptionHandler<\/code> metodu ile dependecy olarak uygulamaya ilgili servisi ekliyor, <strong><em>6.<\/em><\/strong> sat\u0131rda da olas\u0131 hatan\u0131n detaylar\u0131na dair bir yan\u0131t olu\u015fturabilmek i\u00e7in <code>AddProblemDetails<\/code> servisini dahil ediyoruz. Ve son olarak da <strong><em>10.<\/em><\/strong> sat\u0131rda oldu\u011fu gibi <code>UseExceptionHandler<\/code> middleware&#8217;ini \u00e7a\u011f\u0131rarak <code>ExceptionHandlerMiddleware<\/code>&#8216;i devreye sokuyoruz.<\/p>\n<p>Uygulamay\u0131 bu vaziyette derleyip, \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131m\u0131zda olas\u0131 hata durumlar\u0131nda exception handler s\u0131n\u0131f\u0131n\u0131n \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 a\u015fa\u011f\u0131daki gibi g\u00f6zlemleyebiliriz;<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2024\/01\/Asp.NET-Core-8-Global-Error-Handling.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2024\/01\/Asp.NET-Core-8-Global-Error-Handling.png\" alt=\"Asp.NET Core 8 - Global Error Handling\" width=\"655\" height=\"76\" class=\"aligncenter size-full wp-image-26854\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2024\/01\/Asp.NET-Core-8-Global-Error-Handling.png 655w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2024\/01\/Asp.NET-Core-8-Global-Error-Handling-300x35.png 300w\" sizes=\"auto, (max-width: 655px) 100vw, 655px\" \/><\/a><\/p>\n<p>Ayr\u0131ca birden fazla exception handler s\u0131n\u0131f\u0131n\u0131 da uygulamaya dahil edebilir ve olas\u0131 hata durumuna kar\u015f\u0131n kaydedilme s\u0131ras\u0131na g\u00f6re kontrol sa\u011flayabilirsiniz. \u015e\u00f6yle ki;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class DivideByZeroExceptionHandler(ILogger&lt;DivideByZeroExceptionHandler&gt; logger) : IExceptionHandler\r\n    {\r\n        public async ValueTask&lt;bool&gt; TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)\r\n        {\r\n            if (exception is not DivideByZeroException)\r\n                return false;\r\n\r\n            string errorMessage = $&quot;Bir hata olu\u015ftu. Hata mesaj\u0131 :  {exception.Message}&quot;;\r\n            logger.LogError(exception, errorMessage);\r\n\r\n            httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;\r\n            await httpContext.Response.WriteAsJsonAsync(new\r\n            {\r\n                Title = exception.GetType().ToString(),\r\n                Status = httpContext.Response.StatusCode,\r\n                Message = errorMessage\r\n            });\r\n\r\n            return true;\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class NullReferenceExceptionHandler(ILogger&lt;NullReferenceExceptionHandler&gt; logger) : IExceptionHandler\r\n    {\r\n        public async ValueTask&lt;bool&gt; TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)\r\n        {\r\n            if (exception is not NullReferenceException)\r\n                return false;\r\n\r\n            string errorMessage = $&quot;Bir hata olu\u015ftu. Hata mesaj\u0131 :  {exception.Message}&quot;;\r\n            logger.LogError(exception, errorMessage);\r\n\r\n            httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;\r\n            await httpContext.Response.WriteAsJsonAsync(new\r\n            {\r\n                Title = exception.GetType().ToString(),\r\n                Status = httpContext.Response.StatusCode,\r\n                Message = errorMessage\r\n            });\r\n\r\n            return true;\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<p>Burada olu\u015fturdu\u011fumuz exception handler s\u0131n\u0131flar\u0131na dikkat ederseniz, davran\u0131\u015fsal olarak al\u0131nan hata kontrol edilmekte ve uygun olmad\u0131\u011f\u0131 taktirde false de\u011feri d\u00f6nd\u00fcr\u00fclerek exception handle&#8217;\u0131n o s\u0131n\u0131fta olmayaca\u011f\u0131 ifade edilmektedir. B\u00f6ylece bir sonraki handler s\u0131n\u0131f\u0131 devreye girecek ve bu s\u00fcre\u00e7 true d\u00f6necek olan handler s\u0131n\u0131f\u0131na kadar devam edecektir! \u0130\u015fte bu y\u00fczden davran\u0131\u015fsal olarak en genel hata t\u00fcr\u00fcne hitap edecek olan handler s\u0131n\u0131f\u0131n\u0131n a\u015fa\u011f\u0131daki gibi en son tan\u0131mlanmas\u0131 gerekecektir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nbuilder.Services.AddExceptionHandler&lt;Global.Error.Handling.Example.New_Method.DivideByZeroExceptionHandler&gt;();\r\nbuilder.Services.AddExceptionHandler&lt;Global.Error.Handling.Example.New_Method.NullReferenceExceptionHandler&gt;();\r\nbuilder.Services.AddExceptionHandler&lt;Global.Error.Handling.Example.New_Method.ExceptionHandler&gt;();\r\n<\/pre>\n<\/div>\n<p>Yani burada bir hata al\u0131nd\u0131\u011f\u0131 taktirde \u00f6nce <code>DivideByZeroExceptionHandler<\/code> kontrol edilecek e\u011fer false d\u00f6nerse ard\u0131ndan <code>NullReferenceExceptionHandler<\/code> kontrol edilecektir. E\u011fer bu da false d\u00f6nerse son olarak da <code>ExceptionHandler<\/code> kontrol edilecektir. S\u00fcre\u00e7te bunlardan herhangi biri true d\u00f6nd\u00fc\u011f\u00fc taktirde di\u011ferleri kontrol edilmeyecektir. Yahut hepsi false d\u00f6nerse kullan\u0131c\u0131ya herhangi bir result d\u00f6nd\u00fcr\u00fclmeyecektir.<\/p>\n<p>Asp.NET Core 8 ile gelmi\u015f olan <code>IExceptionHandler<\/code> ile middleware yakla\u015f\u0131m\u0131na nazaran hata durumlar\u0131na kar\u015f\u0131n daha efektif ve esnek davran\u0131\u015flar sergileyebildi\u011fimiz kanaatindeyim. Bunlar\u0131n d\u0131\u015f\u0131nda tabi ki de middleware&#8217;ler ile de harika sonu\u00e7lar ortaya koydu\u011fumuz a\u015fikar. Haliyle ben deniz, bundan sonraki projelerimde bu yeni yakla\u015f\u0131mdan istifade edecek amma velakin middleware&#8217;leri de yabana atmamaya \u00f6zen g\u00f6sterece\u011fim \ud83d\ude42<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<p>Not : \u00d6rnek \u00e7al\u0131\u015fmaya a\u015fa\u011f\u0131daki github adresinden eri\u015febilirsiniz.<br \/>\n<a href=\"https:\/\/github.com\/gncyyldz\/Global.Error.Handling.Example\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/gncyyldz\/Global.Error.Handling.Example<\/a><\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Geli\u015ftirdi\u011fimiz uygulamalar\u0131m\u0131z\u0131 her ne kadar hassas ve g\u00fcvenilir bir \u015fekilde tasarl\u0131yor olsak da, genellikle yaz\u0131l\u0131mlar\u0131n \u00e7al\u0131\u015fma s\u00fcrecinin do\u011fal bir par\u00e7as\u0131 olan hata durumlar\u0131 ister istemez meydana gelecektirler ve \u00f6zellikle bu durumlar web uygulamalar\u0131&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":26539,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4912,3102,4997],"tags":[4999,5003,5000,1832,5002,5001,4998],"class_list":["post-26851","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-8","category-asp-net-core","category-asp-net-core-8","tag-asp-net-core-8","tag-asp-net-core-error-handling","tag-asp-net-core-exception-handling","tag-error-handling","tag-exception-handler","tag-exception-handling","tag-iexceptionhandler"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/26851","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=26851"}],"version-history":[{"count":6,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/26851\/revisions"}],"predecessor-version":[{"id":26858,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/26851\/revisions\/26858"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/26539"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=26851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=26851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=26851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}