ASP.NET वेब एपि में सभी अखंडित अपवादों को पकड़ें


113

मैं ASP.NET वेब एपि में होने वाले सभी अखंडित अपवादों को कैसे पकड़ सकता हूं ताकि मैं उन्हें लॉग कर सकूं?

अब तक मैंने कोशिश की है:

  • बनाएं और रजिस्टर करें ExceptionHandlingAttribute
  • में एक Application_Errorविधि लागू करेंGlobal.asax.cs
  • की सदस्यता लेना AppDomain.CurrentDomain.UnhandledException
  • की सदस्यता लेना TaskScheduler.UnobservedTaskException

ExceptionHandlingAttributeसफलतापूर्वक अपवाद नियंत्रक कार्रवाई के तरीकों और कार्रवाई फिल्टर के भीतर फेंक दिया जाता है, लेकिन अन्य अपवाद संभाला नहीं कर रहे हैं, उदाहरण के लिए संभालती है:

  • जब किसी IQueryableक्रिया विधि द्वारा लौटाया गया अपवाद निष्पादित करने में विफल रहता है
  • संदेश हैंडलर द्वारा फेंके गए अपवाद (यानी HttpConfiguration.MessageHandlers)
  • नियंत्रक उदाहरण बनाते समय अपवाद

मूल रूप से, यदि कोई अपवाद क्लाइंट में 500 आंतरिक सर्वर त्रुटि को वापस लाने का कारण बनता है, तो मैं चाहता हूं कि यह लॉग इन हो। Application_Errorवेब फॉर्म्स और एमवीसी में इस काम को अच्छी तरह से लागू करना - मैं वेब एप में क्या उपयोग कर सकता हूं?


क्या आपने ASP.NET स्वास्थ्य निगरानी का उपयोग करने की कोशिश की है ? बस इसे सक्षम करें और देखें कि क्या आपका अपवाद इवेंट लॉग में लॉग इन नहीं है।
जॉन सॉन्डर्स

हेल्थ मॉनिटरिंग मेरी MVC पाइपलाइन अपवादों को पकड़ती है, लेकिन मेरी वेब Api पाइपलाइन अपवादों को नहीं।
जो डेलि

धन्यवाद - मुझे यह पता लगाने में
थोड़ा

जवाबों:


156

यह अब WebAPI 2.1 के साथ संभव है ( व्हाट्स न्यू देखें) ):

IExceptionLogger के एक या अधिक कार्यान्वयन बनाएँ। उदाहरण के लिए:

public class TraceExceptionLogger : ExceptionLogger
{
    public override void Log(ExceptionLoggerContext context)
    {
        Trace.TraceError(context.ExceptionContext.Exception.ToString());
    }
}

फिर अपने एप्लिकेशन के HttpConfiguration के साथ रजिस्टर करें, जैसे एक कॉन्फ़िगर कॉलबैक के अंदर:

config.Services.Add(typeof(IExceptionLogger), new TraceExceptionLogger());

या सीधे:

GlobalConfiguration.Configuration.Services.Add(typeof(IExceptionLogger), new TraceExceptionLogger());

7
@NeilBarnwell हाँ, वेब एपीआई 2.1 System.Web.Http विधानसभा संस्करण 5.1.0 से मेल खाती है । तो आपको यहां वर्णित समाधान का उपयोग करने के लिए इस संस्करण या ऊपर की आवश्यकता है। देखें nuget पैकेज संस्करणों
decates

2
कुछ 500 त्रुटियां अभी भी इसे पकड़ नहीं पाती हैं, जैसे। HttpException - दूरस्थ होस्ट ने कनेक्शन बंद कर दिया है। क्या अभी भी वैश्विक एपीआई प्रसंस्करण के बाहर त्रुटियों को संभालने के लिए Global.asax Application_Error के लिए एक जगह है?
अवनर

11
मैं प्यार करता हूँ कि एमएसडीएन पर आधिकारिक डोका कितना विस्तृत है और 99% डेवलपर्स वास्तव में क्या चाहते हैं, त्रुटियों को लॉग करने के लिए कोड की सिर्फ 8 लाइनें हैं।
रॉकलान

20

युवल का उत्तर वेब एपीआई द्वारा पकड़े गए बिना अपवाद के अनुक्रमण प्रतिक्रियाओं को अनुकूलित करने के लिए है, न कि लॉगिंग के लिए, जैसा कि लिंक किए गए पृष्ठ पर दिया गया है । विवरण के लिए पृष्ठ पर कब से उपयोग करें अनुभाग देखें। लकड़हारे को हमेशा कहा जाता है लेकिन हैंडलर को केवल तभी बुलाया जाता है जब प्रतिक्रिया भेजी जा सकती है। संक्षेप में, लकड़हारे का उपयोग करें प्रतिक्रिया को अनुकूलित करने के लॉग इन करें और हैंडलर का ।

वैसे, मैं विधानसभा v5.2.3 का उपयोग कर रहा हूं और ExceptionHandlerकक्षा में HandleCoreविधि नहीं है । बराबर, मुझे लगता है, है Handle। हालाँकि, बस उपवर्ग ExceptionHandler(जैसा कि युवल के जवाब में है) काम नहीं करता है। मेरे मामले में, मुझे IExceptionHandlerनिम्नानुसार लागू करना होगा ।

internal class OopsExceptionHandler : IExceptionHandler
{
    private readonly IExceptionHandler _innerHandler;

    public OopsExceptionHandler (IExceptionHandler innerHandler)
    {
        if (innerHandler == null)
            throw new ArgumentNullException(nameof(innerHandler));

        _innerHandler = innerHandler;
    }

    public IExceptionHandler InnerHandler
    {
        get { return _innerHandler; }
    }

    public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
    {
        Handle(context);

        return Task.FromResult<object>(null);
    }

    public void Handle(ExceptionHandlerContext context)
    {
        // Create your own custom result here...
        // In dev, you might want to null out the result
        // to display the YSOD.
        // context.Result = null;
        context.Result = new InternalServerErrorResult(context.Request);
    }
}

ध्यान दें, लकड़हारे के विपरीत, आप अपने हैंडलर को डिफ़ॉल्ट हैंडलर को बदलकर पंजीकृत करते हैं, न कि जोड़कर।

config.Services.Replace(typeof(IExceptionHandler),
    new OopsExceptionHandler(config.Services.GetExceptionHandler()));

1
यह एक महान समाधान है, यह 'सभी त्रुटियों को पकड़ने या लॉग इन करने' का स्वीकृत समाधान होना चाहिए। मैं कभी यह पता नहीं लगा सका कि जब मैं सिर्फ एक्सेप्शनहैंडलर का विस्तार कर रहा था तो मेरे लिए यह काम क्यों नहीं किया।
राजीव

महान समाधान। एक बार एमवीसी पाइपलाइन को एक अनुरोध के लिए लोड किया गया है तो यह बहुत अच्छा काम करता है। IIS तब भी अपवादों को संभालता है, जब तक स्टार्टअप में OWIN को स्पिन करना शामिल है। हालांकि, कुछ बिंदु पर स्पिन अप करने के बाद स्टार्टअप की प्रोसेसिंग खत्म हो जाती है। क्योंकि यह आश्चर्यजनक रूप से काम करता है।
गुस्टिन

18

मेरे अपने प्रश्न का उत्तर देने के लिए, यह संभव नहीं है!

आंतरिक सर्वर त्रुटियों का कारण बनने वाले सभी अपवादों को संभालना एक बुनियादी क्षमता की तरह लगता है जो वेब एपीआई के पास होना चाहिए, इसलिए मैंने वेब एपीआई के लिए एक वैश्विक त्रुटि हैंडलर के लिए Microsoft से अनुरोध किया है :

https://aspnetwebstack.codeplex.com/workitem/1001

यदि आप सहमत हैं, तो उस लिंक पर जाएं और उसके लिए वोट करें!

इस बीच, उत्कृष्ट लेख ASP.NET वेब एपीआई अपवाद हैंडलिंग कुछ अलग-अलग श्रेणियों को त्रुटि को पकड़ने के लिए कुछ अलग तरीके दिखाता है। यह जितना होना चाहिए, उससे अधिक जटिल है, और यह सभी इंटरल सर्वर त्रुटियों को नहीं पकड़ता है , लेकिन यह आज उपलब्ध सबसे अच्छा तरीका है।

अद्यतन: वैश्विक त्रुटि से निपटने को अब लागू किया जाता है और रात के निर्माण में उपलब्ध होता है! इसे ASP.NET MVC v5.1 में जारी किया जाएगा। यहां बताया गया है कि यह कैसे काम करेगा: https://aspnetwebstack.codeplex.com/wikipage?title=Global%20Error%20Handling


लगता है कि वेब एपीआई के बजाय अजाक्स कॉल के लिए नियंत्रक का उपयोग करने के लिए एक कारण की तरह लगता है .. सीमाएं पहले से ही धुंधली हैं .. हालांकि अगर एएलएमएएच इसे कैप्चर करने में सक्षम है, तो शायद एक रास्ता है
सोनिक सोल

4
Web API 2.1 में अब वैश्विक त्रुटि हैंडलिंग जोड़ी गई है। अधिक जानकारी के लिए मेरा जवाब देखें।
घटता है

10

आप IExceptionHandlerइंटरफ़ेस को लागू करके (या ExceptionHandlerबेस क्लास विरासत में ) एक वैश्विक अपवाद हैंडलर भी बना सकते हैं । यह अंतिम होगा जिसे सभी पंजीकृत होने के बाद निष्पादन श्रृंखला में बुलाया जाएगा IExceptionLogger:

IExceptionHandler सभी नियंत्रकों से सभी अखंडित अपवादों को संभालता है। यह सूची में अंतिम है। यदि अपवाद होता है, तो IExceptionLogger को पहले बुलाया जाएगा, फिर नियंत्रक अपवादग्राहकों और यदि अभी भी अनहेल्दी है, तो IExceptionHandler कार्यान्वयन।

public class OopsExceptionHandler : ExceptionHandler
{
    public override void HandleCore(ExceptionHandlerContext context)
    {
        context.Result = new TextPlainErrorResult
        {
            Request = context.ExceptionContext.Request,
            Content = "Oops! Sorry! Something went wrong."        
        };
    }

    private class TextPlainErrorResult : IHttpActionResult
    {
        public HttpRequestMessage Request { get; set; }

        public string Content { get; set; }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            HttpResponseMessage response = 
                             new HttpResponseMessage(HttpStatusCode.InternalServerError);
            response.Content = new StringContent(Content);
            response.RequestMessage = Request;
            return Task.FromResult(response);
        }
    }
}

उस पर और अधिक यहाँ


बस जिज्ञासु, यह रजिस्टर कहाँ है?
ThunD3eR

-1

आपके पास मौजूदा ट्राइ-कैच ब्लॉक हो सकते हैं जिनके बारे में आपको जानकारी नहीं है।

मुझे लगा कि हमारे नए global.asax.Application_Errorतरीके को हमारे विरासत कोड में लगातार अपवादों के लिए नहीं बुलाया जा रहा है।

फिर मुझे कॉल स्टैक के बीच में कुछ ट्राइ-कैच ब्लॉक मिले, जिसे रिस्पॉन्स कहा गया। अपवाद पाठ पर। वह यह था। स्क्रीन पर पाठ को डंप किया फिर अपवाद पत्थर को मार दिया।

इसलिए अपवादों को नियंत्रित किया जा रहा था, लेकिन हैंडलिंग कुछ उपयोगी नहीं कर रही थी। एक बार जब मैंने उन ट्रैप-कैच को ब्लॉक कर दिया, तो उम्मीद के मुताबिक Application_Error विधि से प्रचारित अपवाद।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.