2013-06-11 7 views
20

जब किसी अपवाद को आपके कोड द्वारा फेंक दिया जाता है जिसे नियंत्रक में किसी क्रिया से बुलाया जाता है तो उसे कैसे संभाला जाना चाहिए? मैं सर्वोत्तम प्रथाओं के कई उदाहरण देखता हूं जहां कोई प्रयास-पकड़ बयान नहीं है। उदाहरण के लिए, एक रिपोजिटरी से डेटा तक पहुँचने:नियंत्रक (एएसपी.नेट एमवीसी) में अपवाद हैंडलिंग

public ViewResult Index() 
{ 
    IList<CustomModel> customModels = _customModelRepository.GetAll(); 
    return View(customModels); 
} 

जाहिर है इस कोड को अगर कॉल एक डेटाबेस है कि यह उपयोग नहीं कर सकते करने के लिए है एक अपवाद फेंक सकता है और हम उदाहरण के लिए इकाई की रूपरेखा की तरह एक ORM उपयोग कर रहे हैं।

हालांकि जो कुछ मैं देख सकता हूं वह यह होगा कि अपवाद बबल हो जाएगा और उपयोगकर्ता को एक ग़लत त्रुटि संदेश दिखाएगा।

मुझे हैंडलरर विशेषता के बारे में पता है, लेकिन मुझे लगता है कि अगर यह अनचाहे अपवाद होता है तो यह आपको अधिकतर त्रुटि पृष्ठ पर रीडायरेक्ट करने के लिए उपयोग किया जाता है।

बेशक

, इस कोड को एक कोशिश पकड़ में लिपटे जा सकता है लेकिन अच्छी तरह से अलग नहीं है, खासकर यदि आप अधिक तर्क है:

public ViewResult Index() 
{ 
    if (ValidationCheck()) 
    { 
     IList<CustomModel> customModels = new List<CustomModel>(); 
     try 
     { 
      customModels = _customModelRepository.GetAll(); 
     } 
     catch (SqlException ex) 
     { 
      // Handle exception 
     } 

     if (CustomModelsAreValid(customModels)) 
      // Do something 
     else 
      // Do something else 
    } 

    return View(); 
} 

पहले मैं सभी कोड ऐसा अपवाद फेंक सकता है बाहर निकाला है डाटाबेस डेटाप्रोवाइडर क्लास में कॉल करता है जो त्रुटियों को संभालता है और उपयोगकर्ता को संदेश दिखाने के लिए संदेश वापस देता है।

मैं सोच रहा था कि इसे संभालने का सबसे अच्छा तरीका क्या है? मैं हमेशा एक त्रुटि पृष्ठ पर वापस नहीं आना चाहता क्योंकि कुछ अपवादों को ऐसा नहीं करना चाहिए। इसके बजाए, उपयोगकर्ता को एक त्रुटि संदेश सामान्य दृश्य के साथ प्रदर्शित किया जाना चाहिए। क्या मेरी पिछली विधि सही थी या क्या कोई बेहतर समाधान है?

उत्तर

20

मैं और अधिक उपयोगकर्ता के अनुकूल संदेशों को प्रदर्शित करने के लिए तीन बातें करते हैं:

  1. वैश्विक अपवाद संचालक का लाभ उठाएं। एमवीसी के मामले में: Global.asax में Application_Error। यहां इसका उपयोग कैसे करें: http://msdn.microsoft.com/en-us/library/24395wz3(v=vs.100).aspx
  2. मैं अपवाद को UserFriendlyException में उपclass करता हूं। मैं अपने सभी अंतर्निहित सेवा वर्गों में एक सादे पुराने अपवाद के बजाय इस उपयोगकर्ताफ्रेंडली अपवाद को फेंकने के लिए अपनी पूरी कोशिश करता हूं। मैं हमेशा इन कस्टम अपवादों में उपयोगकर्ता-सार्थक संदेश डालने का प्रयास करता हूं। जिसका मुख्य उद्देश्य Application_Error विधि में अपवाद पर एक प्रकार की जांच करने में सक्षम होना है। UserFriendlyExceptions के लिए, मैं केवल उपयोगकर्ता के अनुकूल संदेश का उपयोग करता हूं जिसे मैंने अपनी सेवाओं में गहराई से सेट किया है, जैसे "अरे! 91 डिग्री मान्य अक्षांश मान नहीं है!"। यदि यह एक नियमित अपवाद है, तो यह कुछ मामला है जिसे मैंने संभाला नहीं है, इसलिए मैं एक अधिक सामान्य त्रुटि संदेश प्रदर्शित करता हूं, जैसे "ओह, कुछ गड़बड़ हुई! हम इसे ठीक करने के लिए अपनी पूरी कोशिश करेंगे!"।
  3. मैं एक त्रुटि नियंत्रक भी बनाता हूं जो उपयोगकर्ता के अनुकूल विचार या JSON को प्रस्तुत करने के लिए ज़िम्मेदार है। यह नियंत्रक है जिसका तरीका Application_Error विधि से कहा जाएगा।

संपादित करें: मैंने सोचा कि मैं ASP.NET वेब एपीआई के एक उल्लेख देना चाहते हैं, क्योंकि यह निकट से संबंधित है। चूंकि वेब एपीआई एंडपॉइंट्स का उपभोक्ता एक ब्राउज़र नहीं होगा, इसलिए मैं त्रुटियों से थोड़ा अलग तरीके से निपटना चाहता हूं। मैं अभी भी "FriendlyException" (ऊपर # 2) का उपयोग करता हूं, लेकिन एक त्रुटि नियंत्रक को रीडायरेक्ट करने की बजाय, मैं बस अपने सभी एंडपॉइंट्स को किसी प्रकार का मूल प्रकार देता हूं जिसमें त्रुटि संपत्ति होती है। इसलिए, यदि कोई अपवाद वेब एपीआई नियंत्रकों तक सभी तरह से बुलबुले करता है, तो मैं एपीआई प्रतिक्रिया की त्रुटि प्रॉपर्टी में उस त्रुटि को चिपकाना सुनिश्चित करता हूं। यह त्रुटि संदेश या तो दोस्ताना संदेश होगा जो एपीआई नियंत्रक पर निर्भर करता है, या यह एक सामान्य संदेश होगा यदि अपवाद प्रकार मित्रवत अपवाद नहीं है। इस तरह, उपभोक्ता ग्राहक यह जांच सकता है कि एपीआई प्रतिक्रिया की त्रुटि संपत्ति खाली है या नहीं। त्रुटि मौजूद होने पर एक संदेश प्रदर्शित करें, यदि सामान्य नहीं है तो सामान्य रूप से आगे बढ़ें। अच्छी बात यह है कि, दोस्ताना संदेश अवधारणा के कारण, संदेश सामान्य "त्रुटि" की तुलना में उपयोगकर्ता के लिए अधिक अर्थपूर्ण हो सकता है। संदेश। मैं ज़ैमरिन के साथ मोबाइल ऐप लिखते समय इस रणनीति का उपयोग करता हूं, जहां मैं अपनी वेब सेवाओं और मेरे आईओएस/एंड्रॉइड ऐप के बीच अपना सी # प्रकार साझा कर सकता हूं।

+1

मैं भी पैट्रिक Desjardins 'जवाब से सहमत: अधिभावी त्रुटियों को संभालने के लिए ऑनएक्सप्शन एक शानदार तरीका है। विशेष रूप से यदि यह आधार नियंत्रक में है कि आपके सभी अन्य नियंत्रकों से प्राप्त होता है। – NovaJoe

0

इस तरह के सभी प्रश्न बहुत रचनात्मक नहीं हैं, क्योंकि उत्तर हमेशा "यह निर्भर करता है", क्योंकि त्रुटि प्रबंधन से निपटने के कई तरीके हैं।

कई लोग हैंडलरर विधि का उपयोग करना पसंद करते हैं, क्योंकि कोई अपवाद मूल रूप से गैर-पुनर्प्राप्ति योग्य है। मेरा मतलब है, अगर आप वस्तुओं को वापस नहीं कर सकते हैं तो आप क्या करने जा रहे हैं? आप उन्हें किसी भी तरह से एक त्रुटि दिखाने जा रहे हैं, है ना?

प्रश्न बन जाता है, आप उन्हें त्रुटि कैसे दिखाना चाहते हैं। यदि उन्हें एक त्रुटि पृष्ठ दिखाना स्वीकार्य है, हैंडलरर ठीक से काम करता है, और त्रुटि लॉग करने के लिए एक आसान स्थान प्रदान करता है। यदि आप अजाक्स का उपयोग कर रहे हैं या कुछ फैनसीयर चाहते हैं, तो आपको ऐसा करने का एक तरीका विकसित करना होगा।

आप डेटाप्रोवाइडर क्लास के बारे में बात करते हैं। यह मूल रूप से आपका रिपोजिटरी क्या है। अपने भंडार में क्यों न बनाएं?

16

Asp.Net MVC के साथ आप अपने नियंत्रक के लिए ऑनएक्सप्शन विधि को ओवरराइड भी कर सकते हैं।

protected override void OnException(ExceptionContext filterContext) 
{ 
    if (filterContext.ExceptionHandled) 
    { 
     return; 
    } 
    filterContext.Result = new ViewResult 
    { 
     ViewName = ... 
    }; 
    filterContext.ExceptionHandled = true; 
} 

यह आपको एक संदेश है कि अपवाद को देखें यदि आप चाहते हैं के साथ एक कस्टम त्रुटि पृष्ठ पर रीडायरेक्ट करने के लिए अनुमति देते हैं।

+0

मई डाउनवॉटर थोड़ा तर्क देते हैं: इस उत्तर में क्या गलत है? – Askolein

+1

@Askolein मैं या तो समझ में नहीं आता। यदि आप मानते हैं कि यह एक संभावित समाधान है, तो आप इसे वापस 0 पर सेट करने के लिए वोट दे सकते हैं। –

+0

और यह किया गया है ... +1 – Askolein

1

मैं एक OnException ओवरराइड इस्तेमाल किया क्योंकि मैं एक एक नियंत्रक कि त्रुटियों को संभालने है कि करने के लिए कई परियोजनाओं referenes है:

सुरक्षा/HandleErrorsController.cs

protected override void OnException(ExceptionContext filterContext) 
{ 
    MyLogger.Error(filterContext.Exception); //method for log in EventViewer 

    if (filterContext.ExceptionHandled) 
     return; 

    filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError; 

    filterContext.Result = new JsonResult 
    { 
     Data = new 
     { 
      Success = false, 
      Error = "Please report to admin.", 
      ErrorText = filterContext.Exception.Message, 
      Stack = filterContext.Exception.StackTrace 
     }, 
     JsonRequestBehavior = JsonRequestBehavior.AllowGet 
    }; 
    filterContext.ExceptionHandled = true; 
} 
+2

उपयोगकर्ताओं को संदेशों और स्टैक निशान जैसे कच्चे अपवाद सामग्री को वापस करना वास्तव में एक बुरा विचार है। –

संबंधित मुद्दे