प्रतिक्रिया-अपोलो उपयोग के साथ त्रुटियों को संभालना म्यूटेशन हुक


10

मैं इस समस्या के आसपास अपना सिर पाने की कोशिश कर रहा हूं, लेकिन इसका कोई ठोस जवाब नहीं मिला है। मैं useMutation हुक का उपयोग करके एक लॉगिन म्यूटेशन निष्पादित करने का प्रयास कर रहा हूं।

TLDR; मैं यह जानना चाहता हूं कि उपयोगमुटेशन द्वारा मुझे दिए गए विकल्पों और त्रुटि में पारित ऑनर्रर के बीच वास्तव में क्या अंतर है

यहाँ मेरा कोड स्निपेट है

const [login, { data, loading, error }] = useMutation(LOGIN_QUERY, {
        variables: {
            email,
            password
        },
        onError(err) {
            console.log(err);
        },
});

सर्वर-साइड पर, मेरे पास एक प्रीसेट / हार्डकोड है जो लॉगिन के लिए उपयोग किया जाता है और मैं अपोलो या किसी अन्य क्लाइंट का उपयोग नहीं कर रहा हूं। इस लॉगिन म्यूटेशन के रिज़ॉल्वर में, मैं बस एक त्रुटि फेंकता हूं यदि ईमेल का उपयोग नहीं हो रहा है

throw new Error('Invalid Email');

अब मैं क्लाइंट-साइड (प्रतिक्रिया) पर इस त्रुटि को संभालना चाहता हूं। लेकिन मेरी चिंता यह है कि अगर मैं यूट्यूटेशन हुक से लौटे 'एरर' का इस्तेमाल करता हूं और इस तरह से एरर दिखाने की कोशिश करता हूं

render() {
...
{error && <div> Error occured </div>}
...
}

UI में त्रुटि को अद्यतन किया जाता है, लेकिन फिर तुरंत प्रतिक्रिया मुझे अनहेल्ड रिजेक्शन (त्रुटि) के साथ एक स्क्रीन दिखाती है: ग्राफ़िकल त्रुटि: My-custom-error-message

लेकिन, अगर मैं onMrate फ़ंक्शन का उपयोग करने के लिए विकल्पों में पारित onError का उपयोग करता हूं, तो यह मुझे यह स्क्रीन नहीं दिखाता है और मैं जो कुछ भी चाहता हूं वह त्रुटि के साथ कर सकता हूं।

मैं यह जानना चाहता हूं कि उपयोग में लाए गए विकल्पों और त्रुटि में दिए गए ऑनर्रोर के बीच वास्तव में क्या अंतर है और उपयोग पर प्रतिक्रिया मुझे क्यों दिखाई देती है जब ऑनर्र का उपयोग नहीं किया जाता है तो त्रुटि स्क्रीन दिखाई देती है ।

धन्यवाद!

जवाबों:


32

अपोलो अपने एपीआई के माध्यम से दो प्रकार की त्रुटियों को उजागर करता है: ग्राफकॉल त्रुटियां , जो प्रतिक्रिया के भाग के रूप में errors, साथ dataमें और नेटवर्क त्रुटियों के रूप में वापस आती हैं जो अनुरोध के विफल होने पर होती हैं। एक नेटवर्क त्रुटि तब होगी जब एक सर्वर तक नहीं पहुंचा जा सकता है या यदि प्रतिक्रिया की स्थिति 200 के अलावा कुछ भी नहीं है - errorsप्रतिक्रिया में जो प्रश्न हैं, उनमें अभी भी 200 की स्थिति हो सकती है। लेकिन उदाहरण के लिए, एक अमान्य क्वेरी, जिसके परिणामस्वरूप होगी एक 400 की स्थिति और अपोलो क्लाइंट में एक नेटवर्क त्रुटि।

अपोलो क्लाइंट वास्तव में म्यूटेशन त्रुटियों को संभालने के लिए चार अलग-अलग तरीके प्रदान करता है:

1.) mutateहुक द्वारा लौटाए गए फ़ंक्शन को कॉल करना एक वादा देता है। यदि अनुरोध सफल होता है, तो वादा एक प्रतिक्रिया ऑब्जेक्ट को हल करेगा जिसमें dataसर्वर द्वारा लौटाया गया है। यदि अनुरोध विफल हो जाता है, तो वादा त्रुटि के साथ अस्वीकार होगा । यही कारण है कि आप कंसोल में एक "अनहेल्ड रिजेक्शन" संदेश देखते हैं - आपको अस्वीकार किए गए वादे को संभालने की आवश्यकता है।

login()
  .then(({ data }) => {
    // you can do something with the response here
  })
  .catch(e => {
    // you can do something with the error here
  })

या async / प्रतीक्षा सिंटैक्स के साथ:

try {
  const { data } = await login()
} catch (e) {
  // do something with the error here
}

डिफ़ॉल्ट रूप से, वादा पर अस्वीकार कर देंगे या तो GraphQL त्रुटि या नेटवर्क त्रुटियों। त्रुटि को निर्धारित करके , ignoreया all, हालाँकि, वादा केवल नेटवर्क त्रुटियों पर अस्वीकार होगा । इस स्थिति में, ग्राफ़कॉल त्रुटियां अभी भी प्रतिक्रिया ऑब्जेक्ट के माध्यम से सुलभ होंगी, लेकिन वादा हल होगा।

2.) उपरोक्त का एकमात्र अपवाद तब होता है जब आप एक onErrorफ़ंक्शन प्रदान करते हैं। इस मामले में, वादा हमेशा खारिज करने के बजाय हल होगा, लेकिन यदि कोई त्रुटि होती है, onErrorतो परिणामी त्रुटि के साथ बुलाया जाएगा। errorPolicyआप सेट यहाँ भी लागू होता है - onErrorहमेशा नेटवर्क त्रुटियों के लिए बुलाया जाएगा, लेकिन जब डिफ़ॉल्ट का उपयोग केवल GraphQL त्रुटियों के साथ बुलाया जाएगा errorPolicyकी none। उपयोग करना onErrorअस्वीकार किए गए वादे को पकड़ने के बराबर है - यह केवल mutateफ़ंक्शन के कॉल साइट से हुक के कॉल साइट पर त्रुटि हैंडलर को स्थानांतरित करता है ।

3.) mutateफ़ंक्शन के अतिरिक्त , useMutationहुक भी एक परिणाम वस्तु देता है। यह ऑब्जेक्ट म्यूटेशन चलाते समय आई किसी भी त्रुटि को भी उजागर करता है। ऊपर लिखे गए त्रुटि हैंडलर फ़ंक्शन के विपरीत, यह errorऑब्जेक्ट एप्लिकेशन स्थिति का प्रतिनिधित्व करता है । इस तरह से उजागर की गई दोनों वस्तुएं errorऔर dataवस्तुएं एक सुविधा के रूप में मौजूद हैं। वे ऐसा करने के बराबर हैं :

const [mutate] = useMutation(YOUR_MUTATION)
const [data, setData] = useState()
const [error, setError] = useState()
const handleClick = async () => {
  try {
    const { data } = await mutate()
    setData(data)
  catch (e) {
    setError(e)
  }
}

इस तरह की त्रुटि स्थिति होने पर उपयोगी हो सकता है जब आप चाहते हैं कि आपका UI इस तथ्य को प्रतिबिंबित करे। उदाहरण के लिए, आप एक तत्व का रंग बदल सकते हैं जब तक कि म्यूटेशन बिना किसी त्रुटि के नहीं चलता। उपरोक्त बॉयलरप्लेट को स्वयं लिखने के बजाय, आप केवल उपलब्ध परिणाम ऑब्जेक्ट का उपयोग कर सकते हैं।

const [mutate, { data, error }] = useMutation(YOUR_MUTATION)

नोट: जब आप अपने UI को अपडेट करने के लिए उजागर त्रुटि स्थिति का उपयोग कर सकते हैं, तो ऐसा करना वास्तव में त्रुटि को संभालने के लिए एक विकल्प नहीं है । अनहेल्दी प्रॉमिस रिजेक्शन के बारे में चेतावनी से बचने के लिए आपको या तो कॉलबैक या त्रुटि प्रदान करनी होगीonErrorcatch

4.) अंत में, आप अपने अनुरोधों के लिए वैश्विक त्रुटि हैंडलिंग को जोड़ने के लिए अपोलो-लिंक-त्रुटि का भी उपयोग कर सकते हैं । यह आपको उदाहरण के लिए, एक त्रुटि संवाद प्रदर्शित करने की अनुमति देता है, भले ही आपके आवेदन में अनुरोध उत्पन्न हुआ हो।

आपके आवेदन में आपके द्वारा उपयोग की जाने वाली इन विधियों में से कौन सा आप बहुत कुछ इस पर निर्भर करता है कि आप क्या करने की कोशिश कर रहे हैं (वैश्विक बनाम स्थानीय, राज्य बनाम कॉलबैक, आदि)। अधिकांश अनुप्रयोग त्रुटि से निपटने के एक से अधिक तरीकों का उपयोग करेंगे।


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