मेरे पास एक आंतरिक एपीआई है जिसे मैं डेटा पोस्ट करना चाहता हूं। कुछ मामलों पर निर्भर करता है, मुझे त्रुटियां दिखाई दे रही हैं। तो मैं जो करना चाहता हूं वह यह है कि अगर कोई त्रुटि हुई तो उसे फिर से कॉल करना है।

मैंने जो किया वह इसे फ़ंक्शन में पास करने के लिए काउंटर बनाना था और फ़ंक्शन को नीचे के रूप में पुनरावर्ती रूप से कॉल करना था। यह मुझे नीचे की तरह त्रुटि देता है:

UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block or by rejecting a promise which was not handled with .catch(). (rejection id: 1)

यहां बताया गया है कि मैं फ़ंक्शन को कैसे कॉल करता हूं:

....
private RETRY_API = 1;
....

 try {
    await this.callAPI(request, this.RETRY_API);
} catch (error) {
    console.log('error', error);
}

यह प्रोग्राम ऊपर के कैच ब्लॉक में कभी नहीं आता है।

और यहां मेरा वास्तविक कार्य है जिसे मैं एपीआई कहता हूं:

private async callAPI(request, retry) {
    return new Promise((resolve, reject) => {
       someService.postApiRequest('api/url', request, async(err: any, httpCode: number, data) => {
     if (this.RETRY_API == 2) {
         return reject(err);
      } else if (err) {
          this.callAPI(request, retry);
          this.RETRY_API++;
      } else if ( httpCode !== 200 ) {
          this.RETRY_API = 2;
          // some stuff
      } else {
           this.RETRY_API = 2;
           // some stuff
           return resolve(data);
      }
   });
  })
}

मुझे यकीन नहीं है कि मैं क्या खो रहा हूँ। यदि कोई त्रुटि होने पर एपीआई को दो बार कॉल करने का कोई बेहतर तरीका है, तो यह बहुत अच्छा होगा यदि आप मुझे बताएं।

-1
GoGo 13 सितंबर 2021, 22:39

4 जवाब

सबसे बढ़िया उत्तर

आइए थोड़ा अलग तरीके से व्यवस्थित करें। सबसे पहले, एपीआई के लिए एक वादा-आवरण ...

private async callAPI(request) {
  return new Promise((resolve, reject) => {
    someService.postApiRequest('api/url', request,(err: any, httpCode: number, data) => {
      err ? reject(err) : resolve(data);
    });
  });
}

एक वादे के साथ सेटटाइमआउट का उपयोग करने के लिए एक उपयोगिता कार्य ...

async function delay(t) {
  return new Promise(resolve => setTimeout(resolve, t));
}
  

अब, एक फ़ंक्शन जो कॉल करता है और देरी से पुनः प्रयास करता है ...

private async callAPIWithRetry(request, retryCount=2, retryDelay=2000) {
  try {
    return await callAPI(request);
  } catch (error) {
    if (retryCount <= 0) throw err;
    await delay(retryDelay);
    return callAPIWithRetry(request, retryCount-1, retryDelay);
  }
}

यदि आप किसी अन्य तरीके से त्रुटि पथ का परीक्षण करने के लिए एपीआई पर विफलता को मजबूर नहीं कर सकते हैं, तो आप कम से कम इसे आजमा सकते हैं ...

private async callAPIWithRetry(request, retryCount=2, retryDelay=2000) {
  try {
    // I hate to do this, but the only way I can test the error path is to change the code here to throw an error
    // return await callAPI(request);
    await delay(500);
    throw("mock error");
  } catch (error) {
    if (retryCount <= 0) throw err;
    await delay(retryDelay);
    return callAPIWithRetry(request, retryCount-1, retryDelay);
  }
}
1
danh 13 सितंबर 2021, 23:58

ऐसा लगता है कि आपको callAPI फ़ंक्शन में this.callAPI(request, retry); लाइन की शुरुआत में return await जोड़ने की जरूरत है।

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

0
xgmexgme 13 सितंबर 2021, 22:49

जब मैंने axios' इंटरसेप्टर फ़ंक्शन.

यहां एक कोड स्निपेट है जिसकी आप समीक्षा कर सकते हैं:

axios.interceptors.response.use(
    // function called on a successful response 2xx
    function (response) {
        return response;
    },
    // function called on an error response ( not 2xx )
    async function (error) {
        const request = error.config as AxiosRequestConfig;
        
        // request is original API call
        
        // change something about the call and try again
        // request.headers['Authorization'] = `Bearer DIFFERENT_TOKEN`;
        // return axios(request)
        
        // or Call a different API
        // const new_data = await axios.get(...).then(...)
        // return new_data
        
        // all else fails return the original error
        return Promise.reject(error)
    }
);

0
M. Stolte 13 सितंबर 2021, 23:05

बदलने का प्रयास करें

if (this.RETRY_API == 2)

साथ

if (this.RETRY_API > 1)
0
Varga Tamas 13 सितंबर 2021, 23:26