मेरे पास एक चेक अपवाद को लपेटने के सही तरीके के बारे में काफी विस्तृत प्रश्न है, और जिस तरह से गुवा इसे करता है। (लंबाई के लिए क्षमा चाहते हैं लेकिन मैं अपने विचार प्रक्रिया नीचे प्राप्त करना चाहते हैं)जावा: चेक अपवादों को लपेटने की मानक विधि
मानक Runnable इंटरफ़ेस इस तरह दिखता है:
public interface Runnable
{
public void run();
}
जहां run()
एक जाँच अपवाद नहीं फेंक सकते हैं।
तो अगर मैं जो कार्यों के लिए जो अपवाद जाँच फेंक रैप करने के लिए प्रयोग किया जाता है एक Runnable
करना चाहते हैं, और मैं बात उन अपवादों, बल्कि Runnable.run()
में खुद से संभाल Runnable.run()
कॉल करने के लिए करना चाहते हैं, मैं में अपवाद रैप करने के लिए है एक अनचेक अपवाद।
तो थोड़ी देर के लिए मैं उपयोग कर रहा था:
Runnable r = new Runnable {
@Override public void run()
{
try {
doNastyStuff();
}
catch (NastyException e)
{
throw new RuntimeException(e);
}
}
};
और उसके बाद मैं एक ऊपरी स्तर में RuntimeException संभाल कर सकते हैं। तो सिवाय मैं लगा, कि क्या मैं वास्तव में चाहते हैं अलग से एक लिपटे अपवाद को संभालने के लिए, के बाद से मैं जानता हूँ कि इसके सिमेंटिक एक जाँच अपवाद रैप करने के लिए हो रहा है, इसलिए मैं इस सहायक वर्ग ने लिखा है:
/**
* Wrapped exception: the purpose of this is just to wrap another exception,
* and indicate that it is a wrapped exception
*/
public class WrappedException extends RuntimeException
{
/**
* @param t any throwable
*/
public WrappedException(Throwable t)
{
super(t);
}
}
और फिर मैं यह कर सकता :
/* place that produces the exception */
...
catch (NastyException e)
{
throw new WrappedException(e);
}
...
/* upper level code that calls Runnable.run() */
try
{
...
SomeOtherNastyCode();
r.run();
...
}
catch (SomeOtherNastyException e)
{
logError(e);
}
catch (WrappedException e)
{
logError(e.getCause());
}
और ऐसा लगता है कि यह बहुत अच्छा काम करता है।
लेकिन अब मैं सोच रहा हूं, ठीक है, अगर मैं लाइब्रेरी में इसका उपयोग करना चाहता हूं और लाइब्रेरी का उपयोग करने वाले एक एप्लिकेशन के रूप में, अब वे दोनों लपेटे गए अपवाद पर निर्भर हैं, इसलिए यह वास्तव में मूल पुस्तकालय में होना चाहिए I हर जगह शामिल कर सकते हैं।
जो मुझे सोचता है, शायद अमरूद में मानक मानक लपेटा हुआ वर्ग कहीं है, क्योंकि अब मैं गुवा को डिफ़ॉल्ट रूप से निर्भरता के रूप में शामिल करता हूं। तो मैं सिर्फ
throw new WrappedException(e);
या
throw Exceptions.wrap(e);
या
Exceptions.rethrow(e);
मैं सिर्फ अमरूद में चारों ओर देखा और Throwables जो Throwables.propagate()
कि समान दिखता है पाया है, लेकिन यह सिर्फ लपेटता जांचे हुए अपवादों कर सकते हैं RuntimeException के एक विशेष उप-वर्ग के बजाय RuntimeException
में।
कौन सा दृष्टिकोण बेहतर है? क्या मुझे RuntimeException की तुलना में एक विशेष लपेटा अपवाद का उपयोग नहीं करना चाहिए? मेरा शीर्ष-स्तरीय कोड शीर्षतम अपवाद जानना चाहता है जो सूचनात्मक मूल्य जोड़ता है।
यदि मेरे पास एक रनटाइम अपवाद है जो एक NullEoinception को लपेटता है जो एक NullPointerException को लपेटता है, तो रैपिंग रनटाइम अपवाद सूचनात्मक मूल्य नहीं जोड़ता है, और मुझे इसकी परवाह नहीं है, इसलिए त्रुटि जो मैं लॉग करूंगा वह गंदा अपवाद होगा।
यदि मेरे पास एक अवैध आर्ग्यूमेंट अपवाद है जो एक गंदा अपवाद को लपेटता है, तो IllegalArgumentException आम तौर पर सूचनात्मक मूल्य जोड़ता है।
तो मेरी शीर्ष कोड है कि त्रुटि लॉगिंग करता है, मैं इस तरह कुछ करने के लिए चाहते हैं:
catch (RuntimeException re)
{
logError(getTheOutermostUsefulException(re));
}
/**
* heuristics to tease out whether an exception
* is wrapped just for the heck of it, or whether
* it has informational value
*/
Throwable getTheOutermostUsefulException(RuntimeException re)
{
// subclasses of RuntimeException should be used as is
if (re.getClass() != RuntimeException)
return re;
// if a runtime exception has a message, it's probably useful
else if (re.getMessage() != null)
return re;
// if a runtime exception has no cause, it's certainly
// going to be more useful than null
else if (re.getCause() == null)
return re;
else
return re.getCause();
}
दर्शन मेरे लिए सही लगता है, लेकिन कार्यान्वयन बुरा लगता है। लपेटा अपवादों को संभालने का कोई बेहतर तरीका है?
संबंधित प्रश्नों:
- How do I use Throwables.propagateIfInstanceOf() from Google Guava?
- Wrapping a checked exception into an unchecked exception in Java?
लॉग के अलावा, आपके शीर्ष-स्तरीय हैंडलिंग कोड क्या करते हैं? जब आप एक जंजीर अपवाद के स्टैक ट्रेस को लॉग करते हैं, तो आपको वैसे भी पूरा निशान मिल जाता है, इसलिए इससे कोई फर्क नहीं पड़ता कि यह लपेटा गया है या नहीं। – artbristol
यदि आप अभी लॉगिंग कर रहे हैं, तो आप सब कुछ लॉग इन करने जा रहे हैं, और यदि आप कुछ वास्तविक हैंडलिंग कर रहे हैं, तो केवल उन अपवादों को अनदेखा करने का प्रयास करें जिन्हें आप संभाल सकते हैं। 'getCause' आपको केवल अनचाहे करने की आवश्यकता है। – trutheality
@artbristol, @trutheality: हाँ, मैंने केवल RuntimeException पर logError() को कॉल करने के बारे में सोचा था। लेकिन मेरे आवेदन में 'logError() 'का एक और हिस्सा उपयोगकर्ता को एक डिस्प्ले है, और मुझे वास्तव में बिना किसी शोर के सबसे उपयोगी संदेश प्रदर्शित करने की आवश्यकता है; वे क्या गलत हो गए, यह जानने के लिए अपवाद स्टैक के माध्यम से नहीं जा रहे हैं, बल्कि वे संदेश देखने जा रहे हैं, और यदि वे स्वयं को समस्या का पता लगा सकते हैं, तो अन्यथा मुझे " मुझे एक रनटाइम अपवाद मिला, मैं क्या करूँ? " –