2015-09-19 11 views
6

से रिटर्निंग त्रुटि मैं अपने ऐप के नेटवर्क अनुरोध करने के लिए रेट्रोफिट के साथ ओकेएचटीपी का उपयोग कर रहा हूं। मैं प्रमाणीकरण के लिए इंटरसेप्टर्स का उपयोग कर रहा हूं और यदि आवश्यक हो तो अनुरोधों को पुनः प्रयास कर रहा हूं।ओकेएचटीपी इंटरसेप्टर (रीट्रोफिट का उपयोग करके)

सर्वर में कभी-कभी अस्थायी समस्याएं होती हैं, और एक खाली निकाय लौटाती है हालांकि प्रतिक्रिया स्थिति 200 ठीक है। इससे मेरा ऐप क्रैश हो जाता है, क्योंकि रेट्रोफिट कॉलबैक के सफलता ब्लॉक को कॉल किया जाता है, कस्टम ऑब्जेक्ट लौटाया जाता है (और जीएसओएन के साथ पार्स किया जाता है) शून्य है, और सफलता कॉलबैक में कोड मानता है कि ऑब्जेक्ट वापस आ गया है।

मैंने पहले से ही सर्वर टीम को इसकी सूचना दी है, लेकिन मैं इसे ठीक से ठीक करना चाहता हूं, बिना पूरे चेक के सभी ऐप के सभी कॉलबैक कोड को लपेटने के बिना।

currenty मैं दो विकल्प के लिए इच्छुक हूँ, हालांकि किसी भी अन्य विचारों बहुत स्वागत है: 1) इंटरसेप्टर (से लौट सिर्फ संवाद 2) कुछ है कि रेट्रोफिट कर देगा रिटर्निंग एक त्रुटि प्रदर्शित इस भी संभव है) और? कॉलबैक के विफलता भाग को कॉल करें।

मेरा कोड नीचे है। जैसा कि आप देख सकते हैं, जब खाली निकाय प्राप्त होता है तो मैं अधिकतम 3 बार अनुरोध का पुनः प्रयास करता हूं।

@Override 
public Response intercept(Chain chain) throws IOException 
{ 
    // First 
    Request request = chain.request(); 
    Response response = chain.proceed(request); 

    .... 
    .... 
    .... 

    // Retry empty body response requests for a maximum of 3 times 
    Integer retryMaxCount = 3; 
    MediaType contentType = response.body().contentType(); 
    String bodyString = response.body().string(); 

    while (bodyString.length() == 0 && retryMaxCount > 0) 
    { 
     //Empty body received!, Retrying... 

     retryMaxCount--; 
     response = chain.proceed(request); 
     bodyString = response.body().string(); 
    } 

    if (bodyString.length() != 0) 
    { 
     // Create and return new response because it was consumed 
     ResponseBody newResponseBody = ResponseBody.create(contentType, bodyString); 
     return response.newBuilder().body(newResponseBody).build(); 
    } 
    else 
    { 
     // WHAT TO WRITE HERE??? 
    } 
} 

बहुत बहुत धन्यवाद।

+8

इंटरसेप्टर से अपवाद क्यों नहीं फेंकते? – mastov

+3

बहुत बहुत धन्यवाद। वह आसान था। यदि आप इसे उत्तर के रूप में पोस्ट करते हैं तो मैं इसे स्वीकार करूंगा। :) –

+0

@mastov यदि आप वहां कोई त्रुटि फेंकते हैं, तो क्या आपका ऐप क्रैश नहीं होगा? आप कॉलबैक में त्रुटि/प्रचार कैसे करते हैं? – Singed

उत्तर

0

बस एक ही परिदृश्य था और इस पोस्ट ने मुझे समाधान को लागू करने में मदद की। सही दिशा को इंगित करने के लिए @ मास्टोव के लिए धन्यवाद।

बैक-एंड एपीआई के साथ काम करना जो हमेशा त्रुटि के बावजूद HTTP 200 लौटाता है। यह त्रुटि का मेरा प्रतिक्रिया नमूना

{"status":403,"message":"Bad User credentials","time":1495597740061,"version":"1.0"} 

यहां इस उत्तर के पूरक के लिए एक सरल कार्यान्वयन है।

public Response intercept(Chain chain) throws IOException { 
     Request request = chain.request(); 
     Response response = chain.proceed(request); 
     ResponseBody body = response.body(); 
     // Only intercept JSON type responses and ignore the rest. 
     if (body != null && body.contentType() != null && body.contentType().subtype() != null && body.contentType().subtype().toLowerCase().equals("json")) { 
      String errorMessage = ""; 
      int errorCode  = 200; // Assume default OK 
      try { 
       BufferedSource source = body.source(); 
       source.request(Long.MAX_VALUE); // Buffer the entire body. 
       Buffer buffer = source.buffer(); 
       Charset charset = body.contentType().charset(Charset.forName("UTF-8")); 
       // Clone the existing buffer is they can only read once so we still want to pass the original one to the chain. 
       String json  = buffer.clone().readString(charset); 
       JsonElement obj = new JsonParser().parse(json); 
       // Capture error code an message. 
       if (obj instanceof JsonObject && ((JsonObject) obj).has("status")) { 
        errorCode = ((JsonObject) obj).get("status").getAsInt(); 
       } 
       if (obj instanceof JsonObject && ((JsonObject) obj).has("message")) { 
        errorMessage= ((JsonObject) obj).get("message").getAsString(); 
       } 
      } catch (Exception e) { 
       Log.e(TAG, "Error: " + e.getMessage()); 
      } 
      // Check if status has an error code then throw and exception so retrofit can trigger the onFailure callback method. 
      // Anything above 400 is treated as a server error. 
      if(errorCode > 399){ 
       throw new Exception("Server error code: " + errorCode + " with error message: " + errorMessage); 
      } 
     } 

     return response; 
    } 
संबंधित मुद्दे