2014-12-29 7 views
6

मैं एक ऐसा एप्लिकेशन बना रहा हूं जहां कोई ग्राहक किसी सर्वर से अनुरोध करता है। सर्वर flodel.Http का उपयोग कर .NET.js और क्लाइंट .NET में लिखा गया है।Flurl.Http कस्टम त्रुटि

जब सर्वर पर कोई अनुरोध विफल रहता है, तो कस्टम त्रुटि संदेश बनाने के लिए हमेशा उपयोगी होता है। कुछ इस तरह:

request.respond(500, { message: "targetid is mandatory" }); 

हालांकि इस ग्राहक के पक्ष और जवाब में JSON सूचना के आधार पर एक FlurlHttpException invokes खो जाए।

सर्वर से गैर-सफल प्रतिक्रिया प्राप्त होने पर मुझे यह JSON जानकारी कैसे प्राप्त हो सकती है?

+0

मुझे लगता है कि मेरा [नया उत्तर] (http://stackoverflow.com/a/28332184/62600) जो आप खोज रहे हैं वह होना चाहिए। –

उत्तर

7

मैं सिर्फ Flurl.Http के लिए एक अद्यतन त्रुटि प्रतिक्रियाओं एक पूरी बहुत कुछ के साथ काम कर करता है कि प्रकाशित किया है आसान।यहाँ एक उदाहरण है:

ex.GetResponseString(); 
ex.GetResponseJson(); // returns a dynamic 

ध्यान दें कि आप await त्रुटि प्रतिसाद शरीर की जरूरत नहीं है:

try { 
    var t = await "http://api.com".GetJsonAsync<T>(); 
} 
catch (FlurlHttpException ex) { 
    var error = ex.GetResponseJson<TError>(); 
} 

कुछ रूपों रहे हैं। चूंकि await आईएन catch ब्लॉक के अंदर सी # 4.5 में समर्थित नहीं है, इसलिए मैं इसे यहां नहीं चाहता था। हालांकि, अभी भी कोई अवरोध नहीं है; मूल प्रतिक्रिया के हिस्से के रूप में त्रुटि प्रतिक्रिया निकाय का इंतजार और कब्जा कर लिया गया है। (चूंकि सामान्य परिस्थितियों में एक स्ट्रिंग के रूप में प्रतिक्रिया शरीर को पूर्ववत रूप से कैप्चर करना एक प्रदर्शन हिट हो सकता है, मैं केवल गैर-सफल प्रतिक्रियाओं के लिए ऐसा कर रहा हूं जहां FlurlHttpException फेंक दिया जाएगा। भविष्य में, मैं इस व्यवहार को कॉन्फ़िगर करने योग्य मान सकता हूं।)

इन वृद्धियों को संस्करण 0.5.0 में जोड़ा गया है और NuGet पर उपलब्ध हैं।

0

मैंने Flurl के स्रोत कोड को संपादित करके इस समस्या का समाधान किया। फ़ाइल में FlurlMessageHandler.cs आपको विधि IsErrorCondition मिल जाएगी जो जांचता है कि कोई त्रुटि हुई है या नहीं। जब भी प्रतिक्रिया में कोड 2xx नहीं होता है तो इसे एक त्रुटि के रूप में देखा जाता है, इस भाग को मैंने टी कोड से हटा दिया और अब मैं मैन्युअल रूप से जांचता हूं कि प्रतिक्रिया में एक succes कोड है या नहीं।

0

आप हालांकि FlurlHttpException.Call में विफल रहा है प्रतिक्रिया है, जो HttpCall का एक उदाहरण, एक नैदानिक ​​उद्देश्य यह है कि (अन्य बातों के अलावा) शामिल हैं कच्चे HttpRequestMessage और HttpResponseMessage है के शरीर प्राप्त कर सकते हैं।

प्रतिक्रिया से बाहर शरीर हो रही एक async कॉल की आवश्यकता है, और दुर्भाग्य से आप एक catch ब्लॉक के अंदर नहीं await, इसलिए मुझे लगता है कि catch ब्लॉक और await के बाद प्रतिक्रिया शरीर ing अंदर विफल रही कॉल पर कब्जा सुझाव देंगे कर सकते हैं। कुछ इस तरह:

HttpCall failedCall = null; 

try { 
    await url.GetAsync(); 
} 
catch (FlurlHttpException ex) { 
    failedCall = ex.Call; 
} 

if (failedCall != null && failedCall.Response != null) { 
    var body = await failedCall.Response.Content.ReadAsStringAsync(); 
    // body now contains the full text of the failed response. 
} 

Flurl यथासंभव कम शोर के साथ एक प्रतिक्रिया POCO के लिए एक आधार के URL से आप हो रही में excels है, यह बेशक अधिक शोर हो जाता है जब आप एक असफल प्रतिक्रिया के शरीर से निपटने के लिए की जरूरत है। मैंने यह देखने के लिए कि क्या मैं यहां कुछ शॉर्टकट्स लेकर आ सकता हूं, मैंने note-to-self खोला है। आपके विचारों के साथ टिप्पणी करने के लिए स्वतंत्र महसूस करें।

+0

मेरे उत्तर में मैं दिखाता हूं कि एसिंक प्रवाह को कैसे रखा जाए। –

+0

@ LayGonzález अगर "एसिंक प्रवाह रखें" का मतलब है कि आप कैच ब्लॉक में प्रतीक्षा कर रहे हैं, तो आप वर्तमान (समर्थित) भाषा/कंपाइलर संस्करण में ऐसा नहीं कर सकते हैं, लेकिन मैं समझता हूं [यह आ रहा है] (http: // ब्लॉग। stephencleary.com/2014/06/await-in-catch-and-finally.html)। –

0

मुझे विश्वास है कि सभी http त्रुटियों को अपवादों के रूप में संभालने में दिलचस्प है। सुनिश्चित नहीं है कि सबसे अच्छा अभ्यास है, लेकिन मैंने इसे आज़माया।

async void FakeLogin() 
{ 
    try{ 
     User user = await LoginWithEmail ("[email protected]", "fakePassword"); 
    } 
    catch(MyApiException e) { 
     MyApiError = e.Error; 
    } 
} 

मूल रूप से

FlurlHttpException मामले के लिए:

public static async Task<User> LoginWithEmail (string email, string password){ 
    try{ 
    return await "http://myapi.com/login" 
       .AppendPathSegment ("login") 
       .SetQueryParams (new {email = email, password = password}) 
       .WithHeader ("Accept", "application/json") 
       .GetJsonAsync<User>(); 
    }catch (FlurlHttpException e) { 
    return await e.Call.Response.Content.ReadAsStringAsync() 
        .ContinueWith<User> ((contentAsync) => { 
         throw new MyApiException(JsonConvert.DeserializeObject<MyApiError> (contentAsync.Result)); }); 
    } 
} 

यह आप इस तरह सफलता और त्रुटि मामलों को संभालने के लिए अनुमति देता है:

मैं क्या कुछ इस तरह है , मैं ReadAsStringAsync के लिए एक निरंतरता करता हूं जहां मैं एक उपयोगकर्ता को वापस करने की निरंतरता की घोषणा करता हूं, लेकिन निरंतरता के अंदर मैं हमेशा एक अपवाद फेंक दो।

इसके अतिरिक्त

आप अपवाद के रूप में कम होने के लिए से निपटने refactor सकता है:

catch (FlurlHttpException e) { 
    return await MyApiException.FromFlurlException<User>(e); 
} 
+0

क्या आप विजुअल स्टूडियो का उपयोग कर रहे हैं? वह * 2015 पूर्वावलोकन में संकलित हो सकता है (कोशिश नहीं की है), लेकिन किसी भी समर्थित रिलीज में नहीं होगा क्योंकि [आप कैच ब्लॉक के अंदर इंतजार नहीं कर सकते] [http://stackoverflow.com/questions/8868123/await -इन-पकड़ ब्लॉक)। –

+0

मैं Xamarin के .Net पीसीएल 78 का उपयोग कर रहा हूं, जो मुझे विश्वास है .net 4.5 है। यह संकलित करता है और यह चलता है, लेकिन अब मुझे यकीन नहीं है कि अपेक्षित (असीमित) चल रहा है। –

+0

@ToddMenier अब मैं पुष्टि कर सकता हूं कि मैं इसे संकलित करने में सक्षम था क्योंकि मैं मोनो का उपयोग कर रहा था। जैसा कि आपने कहा था, विजुअल स्टूडियोज़ 'नेट कैच ब्लॉक के अंदर प्रतीक्षा करने की अनुमति नहीं देगा। –

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