ব্যতিক্রম নিক্ষেপকারীদের ত্রুটিগুলি লগ করা উচিত?


15

আমি কয়েক মাস ধরে একটি অ্যাপ্লিকেশন তৈরি করেছিলাম এবং আমি এমন একটি প্যাটার্ন উপলব্ধি করতে পেরেছিলাম যা উদ্ভূত হয়েছিল:

logger.error(ERROR_MSG);
throw new Exception(ERROR_MSG);

বা, ধরা পড়ার সময়:

try { 
    // ...block that can throw something
} catch (Exception e) {
    logger.error(ERROR_MSG, e);
    throw new MyException(ERROR_MSG, e);
}

সুতরাং, যখনই আমি নিক্ষেপ করছিলাম বা কোনও ব্যতিক্রম ধরছিলাম, আমি এটি লগ করব। আসলে, আমি প্রায় সমস্ত লগইন করেছিলাম অ্যাপ্লিকেশনটিতে (অ্যাপ্লিকেশন প্রারম্ভিককরণের জন্য কিছু)।

সুতরাং, একজন প্রোগ্রামার হিসাবে আমি পুনরাবৃত্তি থেকে দূরে থাকি; সুতরাং আমি লગર কলগুলি ব্যতিক্রম নির্মাণে সরিয়ে নেওয়ার সিদ্ধান্ত নিয়েছি, সুতরাং, যখনই আমি একটি ব্যতিক্রম তৈরি করতাম, জিনিসগুলি লগ করা হত। আমি অবশ্যই একটি এক্সসেপশন হেল্পার তৈরি করতে পেরেছিলাম যা আমার জন্য ব্যতিক্রম ছুঁড়ে ফেলেছে, তবে এটি আমার কোডটি ব্যাখ্যা করা আরও শক্ত করে তুলবে এবং আরও খারাপ এটি যে সংস্থার কাছে কল আসতে পারে তা বুঝতে ব্যর্থ হয়ে সংকলকটি এটির সাথে ভাল আচরণ করবে না ing তাত্ক্ষণিক নিক্ষেপ

সুতরাং, এটি কি একটি বিরোধী নিদর্শন? যদি তাই হয় তবে কেন?


আপনি যদি ব্যতিক্রমটিকে সিরিয়ালাইজ করে এবং ডিসিরিয়ালাইজ করেন তবে কী হবে? এটি লগ ত্রুটি হবে?
সর্বনাশ

উত্তর:


18

এটি কোনও অ্যান্টি-প্যাটার্ন হিসাবে যোগ্যতা অর্জন করেছে কিনা তা নিশ্চিত নন, তবে আইএমও এটি একটি খারাপ ধারণা: লগিংয়ের সাথে ব্যতিক্রমকে জড়িয়ে থাকা অপ্রয়োজনীয় মিলন।

আপনি সর্বদা প্রদত্ত ব্যাতিক্রমের সমস্ত দৃষ্টান্ত লগ করতে না চাইতে পারেন (সম্ভবত এটি ইনপুট বৈধকরণের সময় ঘটে, যার লগিং উভয় প্রকারের বা উদ্বেগজনক হতে পারে)।

দ্বিতীয়ত, আপনি বিভিন্ন লগিং স্তরের সাথে একটি ত্রুটির বিভিন্ন ঘটনা লগ করার সিদ্ধান্ত নিতে পারেন, সেই সময়ে আপনাকে ব্যতিক্রমটি নির্মাণের সময় নির্দিষ্ট করতে হবে যা লগিং আচরণের সাথে ব্যতিক্রম সৃষ্টিকে আবদ্ধ করে তোলে।

অবশেষে, অন্য ব্যতিক্রম লগ করার সময় যদি ব্যতিক্রম ঘটে? আপনি কি লগ ইন করবেন? এটা অগোছালো হয়ে যায় ...

আপনার পছন্দগুলি মূলত:

  • ক্যাচ, লগ এবং পুনরায় নিক্ষেপ করুন, যেমন আপনি আপনার উদাহরণ দিয়েছেন
  • আপনার জন্য উভয়ই করার জন্য একটি এক্সেপশনহেলপার ক্লাস তৈরি করুন, তবে সহায়কদের একটি কোডের গন্ধ আছে, এবং আমি এটিরও সুপারিশ করব না।
  • ক্যাচ-সমস্ত ব্যতিক্রম হ্যান্ডলিংকে একটি উচ্চ স্তরে নিয়ে যান
  • লগিং এবং ব্যতিক্রম হ্যান্ডলিংয়ের মতো ক্রস-কাটিংয়ের উদ্বেগগুলির আরও পরিশীলিত সমাধানের জন্য এওপি বিবেচনা করুন (তবে কেবল আপনার ক্যাচ ব্লকে সেই দুটি লাইন থাকার চেয়ে অনেক জটিল;))

"প্রচুর এবং উদ্বেগহীন" এর জন্য +1। এওপি কি?
তুলাইনস কর্ডোভা

@ user61852 Aspect-oriented প্রোগ্রামিং (আমি একটি লিঙ্ক যুক্ত করেছি)। এই প্রশ্নের শো একটি উদাহরণ W / R / T Aop এবং জাভা লগিং: stackoverflow.com/questions/15746676/logging-with-aop-in-spring
Dan1701

11

সুতরাং, একজন প্রোগ্রামার হিসাবে আমি পুনরাবৃত্তি এড়িয়ে চলি [...]

এখানে বিপদ আছে যখনই ধারণাটিকে "don't repeat yourself"কিছুটা গুরুত্ব সহকারে গ্রহণ করা হয় যেখানে এটি গন্ধ হয়।


2
এখন সবাই কীভাবে সঠিক উত্তরটি বেছে নেওয়ার এবং একে অপরের প্রতি গড়ে তোলার কথা বলব? আমি যদি এর প্রতি অনুরাগী দৃষ্টিভঙ্গি গ্রহণ করি তবে ডিআরওয়াই কীভাবে সমস্যা হয়ে উঠতে পারে তার দুর্দান্ত ব্যাখ্যা।
ব্রুনো ব্রেন্ট

1
এটি ডিআরওয়াই-তে সত্যই ছুরিকাঘাত, আমি অবশ্যই স্বীকার করব যে আমি একজন ডিআরহ্লিক। এখন আমি দুবার বিবেচনা করব যখন আমি ডিআরওয়াইয়ের স্বার্থে এই 5 টি লাইন কোডটি অন্য কোথাও স্থানান্তরিত করার কথা ভাবব।
এসজেডটি

@ জাজামান আমি প্রথমত একই রকম ছিলাম। উজ্জ্বল দিকে আমি মনে করি আমাদের মধ্যে যারা আরও বেশি ঝুঁকছেন তাদের তুলনায় অনেক বেশি ঝুঁকির কথা যারা বলে, কপি এবং পেস্ট ব্যবহার করে 500 লাইনের ফাংশন লেখেন এবং এটিকে পুনর্বিবেচিত করার কথা ভাবেন না। আইএমওকে মনে রাখার মূল বিষয়টি হ'ল প্রতিবার আপনি কিছু ছোট নকলটি মুদ্রণ করেন, আপনি কোডটি বিকেন্দ্রীকরণ করছেন এবং অন্যত্র নির্ভরতা পুনর্নির্দেশ করছেন। এটি হয় ভাল জিনিস বা খারাপ জিনিস হতে পারে। এটি আপনাকে আচরণ পরিবর্তন করার জন্য কেন্দ্রীয় নিয়ন্ত্রণ দেয় তবে সেই আচরণটি ভাগ করে নেওয়া

@ এসজামান আপনি যদি এমন পরিবর্তন করতে চান তবে "কেবল এই ফাংশনটির এটির প্রয়োজন, অন্যরা যারা এই কেন্দ্রীয় ফাংশনটি ব্যবহার করেন তারা তা করেন না।" যাইহোক, এটি যেমন দেখছি তেমনি ভারসাম্যপূর্ণ কাজ - এমন কিছু যা নিখুঁতভাবে করা শক্ত! তবে কখনও কখনও কিছুটা সদৃশ আপনার কোডকে আরও স্বতন্ত্র এবং ডিকোপল করতে সহায়তা করতে পারে। এবং যদি আপনি কোনও কোডের টুকরো পরীক্ষা করে দেখেন এবং এটি সত্যিই ভাল কাজ করে, এমনকি যদি এটি এখানে এবং সেখানে কিছু মৌলিক যুক্তিকে নকল করে দেয় তবে এর পরিবর্তিত হওয়ার কয়েকটি কারণ থাকতে পারে। এদিকে এমন কিছু যা পুরোপুরি বাহ্যিক জিনিসের উপর নির্ভর করে তার পরিবর্তনের জন্য আরও অনেক বাহ্যিক কারণ খুঁজে পায়।

6

প্রতিবেদন করতে @ Dan1701

এটি উদ্বেগের পৃথকীকরণ সম্পর্কে - ব্যতিক্রমের মধ্যে লগিংকে সরিয়ে নিয়ে যাওয়া ব্যতিক্রম এবং লগিংয়ের মধ্যে দৃ coup় সংযোগ তৈরি করে এবং এর অর্থ হ'ল লগিংয়ের ব্যতিক্রমের ক্ষেত্রে আপনি একটি অতিরিক্ত দায়িত্ব যুক্ত করেছেন যা ফলস্বরূপ ব্যতিক্রম শ্রেণির জন্য নির্ভরতা তৈরি করতে পারে দরকার নেই

রক্ষণাবেক্ষণের দৃষ্টিকোণ থেকে আপনি (আমি চাই) যুক্তি দিতে পারেন যে আপনি যে ব্যতিক্রমটি রক্ষণাবেক্ষণকারী (কমপক্ষে উদাহরণের মতো কিছু প্রসঙ্গে) থেকে লগ করা হচ্ছে তা লুকিয়ে রেখেছেন, আপনি প্রসঙ্গটিও পরিবর্তন করছেন ( ব্যতিক্রম হ্যান্ডলারের অবস্থান থেকে ব্যতিক্রমের নির্মাণকারীর কাছে) যা সম্ভবত আপনি চান তা নয়

অবশেষে আপনি একটি ধারণা তৈরি করছেন যে আপনি সর্বদা একটি ব্যতিক্রম লগ করতে চান ঠিক একই ফ্যাশনে, এটি তৈরি / উত্থাপিত সময়ে - যা সম্ভবত এটি নয়। যদি না আপনি লগিং এবং অ-লগিং ব্যতিক্রমগুলি না যা খুব তাড়াতাড়ি গভীর অপ্রীতিকর হয়ে উঠতে পারে।

সুতরাং এই ক্ষেত্রে আমি "এসআরপি" ট্রাম্প "ডিআরওয়াই" ট্রাম্প মনে করি।


1
[...]"SRP" trumps "DRY"- আমি মনে করি এই উদ্ধৃতিটি একেবারে নিখুঁতভাবে সমান।

যেমন @ আইক বলেছেন ... এই ধরণের যুক্তি আমি খুঁজছিলাম।
ব্রুনো ব্রেন্ট

লগিংয়ের প্রেক্ষাপট পরিবর্তন করা লগ করার জন্য +1 দেখায় ব্যতিক্রম শ্রেণিটি মূল বা লগ এন্ট্রি, যা নেই।
তুলাইনস কর্ডোভা

2

আপনার ত্রুটিটি এমন ব্যতিক্রম লগিং করছে যেখানে আপনি এটি পরিচালনা করতে পারবেন না এবং এভাবে লগিং সঠিকভাবে পরিচালনার কোনও অংশ কিনা তা জানতে পারে না।
খুব কম কেস রয়েছে যেখানে আপনি ত্রুটির অংশটি পরিচালনা করতে পারেন বা অবশ্যই পরিচালনা করতে হবে, যার মধ্যে লগিং অন্তর্ভুক্ত থাকতে পারে তবে তবুও অবশ্যই ত্রুটিটিকে কলারের সাথে সংকেত দিতে হবে । উদাহরণগুলি হ'ল সংশোধনযোগ্য পঠন-ত্রুটি এবং এর মতো, যদি আপনি সর্বনিম্ন-স্তরীয় পাঠ করেন তবে সুরক্ষার জন্য এবং ব্যবহারের জন্য, সাধারণভাবে তাদের কাছে সাধারণভাবে বলা আছে যে কলারের কাছে জানানো তথ্য কঠোরভাবে ফিল্টার করা হয়।

আপনার ক্ষেত্রে কেবলমাত্র আপনি যা করতে পারেন এবং কোনও কারণে এটি করা হয়েছে, প্রয়োগকারী কলার প্রত্যাশিত একটিতে ব্যতিক্রমটিকে অনুবাদ করা, প্রসঙ্গে প্রাসঙ্গিকতার জন্য মূল শৃঙ্খলাবদ্ধ করা এবং অন্য যে কোনও কিছুকে ভালভাবে রেখে যাওয়া।

এটি সংক্ষেপে, আপনার কোড ব্যতিক্রমকে আংশিকভাবে পরিচালনা করার জন্য ডান এবং কর্তব্যকে অহংকার করেছিল, সুতরাং এসআরপি লঙ্ঘন করে।
ডিআরওয়াই এর মধ্যে আসে না।


1

কেবলমাত্র আপনি একটি ক্যাচ ব্লক ব্যবহার করে লগ করার সিদ্ধান্ত নিয়েছিলেন বলে ব্যতিক্রমটিকে পুনরায় বাড়িয়ে তোলা (অর্থ ব্যতিক্রমটি মোটেও পরিবর্তিত হয়নি) একটি খারাপ ধারণা।

আমরা ব্যতিক্রম, ব্যতিক্রম বার্তাগুলি এবং এর পরিচালনার ব্যবহারের অন্যতম কারণ হ'ল আমরা কী ভুল বুঝতে পেরেছিলাম এবং চতুরতার সাথে লিখিত ব্যতিক্রমগুলি একটি বড় ব্যবধানে বাগটি খুঁজে পেতে দ্রুত করতে পারে।

এছাড়াও মনে রাখবেন, ব্যতিক্রমগুলি পরিচালনা করার জন্য বলার অপেক্ষা রাখে না যে তার চেয়ে বেশি সংস্থান রয়েছে if, সুতরাং আপনার নিজের মতো লাগার কারণে আপনার সেগুলি প্রায়শই পরিচালনা করা উচিত নয়। এটি আপনার অ্যাপ্লিকেশনটির কার্যকারিতার উপর প্রভাব ফেলে।

অ্যাপ্লিকেশন স্তরটি যাতে ত্রুটিটি উপস্থিত হয়েছিল তা চিহ্নিত করার উপায় হিসাবে ব্যতিক্রমটি ব্যবহার করা তবে এটি ভাল পন্থা।

নিম্নলিখিত আধা ছদ্ম কোডটি বিবেচনা করুন:

interface ICache<T, U>
{
    T GetValueByKey(U key); // may throw an CacheException
}

class FileCache<T, U> : ICache<T, U>
{
    T GetValueByKey(U key)
    {
        throw new CacheException("Could not retrieve object from FileCache::getvalueByKey. The File could not be opened. Key: " + key);
    }
}

class RedisCache<T, U> : ICache<T, U>
{
    T GetValueByKey(U key)
    {
        throw new CacheException("Could not retrieve object from RedisCache::getvalueByKey. Failed connecting to Redis server. Redis server timed out. Key: " + key);
    }
}

class CacheableInt
{
    ICache<int, int> cache;
    ILogger logger;

    public CacheableInt(ICache<int, int> cache, ILogger logger)
    {
        this.cache = cache;
        this.logger = logger;
    }

    public int GetNumber(int key) // may throw service exception
    {
        int result;

        try {
            result = this.cache.GetValueByKey(key);
        } catch (Exception e) {
            this.logger.Error(e);
            throw new ServiceException("CacheableInt::GetNumber failed, because the cache layer could not respond to request. Key: " + key);
        }

        return result;
    }
}

class CacheableIntService
{
    CacheableInt cacheableInt;
    ILogger logger;

    CacheableInt(CacheableInt cacheableInt, ILogger logger)
    {
        this.cacheableInt = cacheableInt;
        this.logger = logger;
    }

    int GetNumberAndReturnCode(int key)
    {
        int number;

        try {
            number = this.cacheableInt.GetNumber(key);
        } catch (Exception e) {
            this.logger.Error(e);
            return 500; // error code
        }

        return 200; // ok code
    }
}

আসুন ধরে নেওয়া যাক যে কেউ ত্রুটি নির্দেশ GetNumberAndReturnCodeকরে 500কোডটি কল করেছে এবং পুনরুদ্ধার করেছে । তিনি সমর্থনটি কল করতেন, যিনি লগ ফাইলটি খুলবেন এবং এটি দেখুন:

ERROR: 12:23:27 - Could not retrieve object from RedisCache::getvalueByKey. Failed connecting to Redis server. Redis server timed out. Key: 28
ERROR: 12:23:27 - CacheableInt::GetNumber failed, because the cache layer could not respond to request. Key: 28

তখন বিকাশকারী তাৎক্ষণিকভাবে জানতে পারে যে সফ্টওয়্যারটির কোন স্তর প্রক্রিয়াটি বাতিল করতে পেরেছিল এবং সমস্যাটি সনাক্ত করার একটি সহজ উপায় রয়েছে। এই ক্ষেত্রে এটি সমালোচনাযোগ্য, কারণ রেডিস সময় নির্ধারণের ফলে কখনই সুখ হয় না।

সম্ভবত অন্য ব্যবহারকারী একই পদ্ধতি কল করবে, কোডটিও গ্রহণ করবে 500, কিন্তু লগতে নিম্নলিখিতটি দেখানো হবে:

INFO: 11:11:11- Could not retrieve object from RedisCache::getvalueByKey. Value does not exist for the key 28.
INFO: 11:11:11- CacheableInt::GetNumber failed, because the cache layer could not find any data for the key 28.

এই ক্ষেত্রে সমর্থনটি সহজেই ব্যবহারকারীকে প্রতিক্রিয়া জানাতে পারে যে অনুরোধটি অবৈধ ছিল কারণ তিনি অস্তিত্বহীন আইডির জন্য একটি মান অনুরোধ করছেন।


সারসংক্ষেপ

আপনি যদি ব্যতিক্রমগুলি পরিচালনা করছেন তবে এগুলি সঠিক উপায়ে পরিচালনা করতে ভুলবেন না। এছাড়াও আপনার ব্যতিক্রমগুলি আপনার আর্কিটেকচার স্তরগুলি অনুসরণ করে প্রথমে সঠিক তথ্য / বার্তা অন্তর্ভুক্ত রয়েছে তা নিশ্চিত করুন, যাতে বার্তাগুলি আপনাকে এমন একটি সমস্যা চিহ্নিত করতে সহায়তা করবে যা ঘটতে পারে।


1

আমি মনে করি সমস্যাটি আরও প্রাথমিক স্তরে রয়েছে: আপনি ত্রুটিটি লগইন করেন এবং এটি একই জায়গায় ব্যতিক্রম হিসাবে ফেলে দেন। এটাই অ্যান্টি-প্যাটার্ন। এর অর্থ একই ভুলটি অনেক সময় লগ হয় যদি এটি ধরা পড়ে, সম্ভবত অন্য ব্যতিক্রমের মধ্যে আবৃত হয়ে আবার ফেলে দেওয়া হয়।

এর পরিবর্তে আমি ত্রুটিগুলি লগ করার পরামর্শ দিচ্ছি যখন ব্যতিক্রমটি তৈরি হবে না, তবে যখন এটি ধরা পড়ে। যখন একটি ব্যতিক্রম ধরা যদি তা না হয় (এই জন্য, অবশ্যই, আপনি নিশ্চিত করুন যে এটি সবসময় ধরা কোথাও করতে হবে।), আমি শুধুমাত্র তার ক্ষেত্রে স্টেকট্র্যাস লগ ইন করুন চাই না পুনরায় নিক্ষিপ্ত বা অন্য ব্যতিক্রম মধ্যে কারণ হিসাবে আবৃত। মোড়ানো ব্যতিক্রমগুলির স্ট্যাকট্রেস এবং বার্তাগুলি যাইহোক, "এর দ্বারা ..." হিসাবে স্ট্যাক ট্রেসগুলিতে লগইন করা হয়েছে। এবং ক্যাচারও প্রথম সিদ্ধান্ত নিতে পারে যেমন প্রথম ব্যর্থতায় ত্রুটিটি লগ না করে পুনরায় চেষ্টা করা বা এটি কেবল একটি সতর্কতা হিসাবে বা যেকোন কিছু হিসাবে বিবেচনা করুন।


1

আমি জানি এটি একটি পুরানো থ্রেড, তবে আমি সবেমাত্র একটি একই সমস্যা জুড়ে এসে একটি অনুরূপ সমাধান বের করেছি যাতে আমি আমার 2 সেন্ট যোগ করব।

আমি এসআরপি লঙ্ঘনের যুক্তিটি কিনছি না। পুরোপুরি যাই হোক না কেন। আসুন ২ টি জিনিস ধরে নিই: ১. আপনি আসলে ব্যতিক্রমগুলি লগ করতে চান (প্রোগ্রামের প্রবাহটি পুনরায় তৈরি করতে সক্ষম হওয়ার জন্য ট্রেস পর্যায়ে)। ব্যতিক্রম পরিচালনার সাথে এর কোনও যোগসূত্র নেই। ২. আপনি পারবেন না বা আপনি এটির জন্য এওপি ব্যবহার করবেন না - আমি সম্মত হলাম এটি যাওয়ার সবচেয়ে ভাল উপায় হবে তবে দুর্ভাগ্যক্রমে আমি এমন একটি ভাষাতে আটকে আছি যা এর জন্য সরঞ্জাম সরবরাহ করে না।

আমি এটি যেভাবে দেখছি, আপনি মূলত একটি বৃহত স্কেল এসআরপি লঙ্ঘনের জন্য সাজা পেয়ে গেছেন, কারণ যে কোনও শ্রেণি যে ব্যতিক্রম ছুঁড়তে চায় তা লগ সম্পর্কে সচেতন হতে হবে। ব্যতিক্রম শ্রেণিতে লগিং সরানো আসলে এসআরপি লঙ্ঘনকে হ্রাস করে কারণ এখন কেবল ব্যতিক্রমগুলি এটিকে লঙ্ঘন করে এবং কোড বেসের প্রতিটি শ্রেণি নয়।


0

এটি একটি অ্যান্টি-প্যাটার্ন।

আমার মতে, একটি ব্যতিক্রমের কনস্ট্রাক্টরে লগিং কল করা নিম্নলিখিতগুলির উদাহরণ হতে পারে: ত্রুটি: নির্মাণকারী রিয়েল ওয়ার্ক করে

আমি কোনও বাহ্যিক পরিষেবা কল করার জন্য কোনও নির্মাণকারীকে কখনই (বা ইচ্ছা) আশা করব না। এটি একটি খুব অনাকাঙ্ক্ষিত পার্শ্ব-প্রতিক্রিয়া যা মাইকো হেভারি উল্লেখ করেছেন, সাবক্লাস এবং মককে অযাচিত আচরণের উত্তরাধিকারী হতে বাধ্য করে।

এই হিসাবে এটি কমপক্ষে অবাক হওয়ার নীতি লঙ্ঘন করবে ।

যদি আপনি অন্যের সাথে কোনও অ্যাপ্লিকেশন বিকাশ করে থাকেন তবে এই পার্শ্ব-প্রতিক্রিয়াটি সম্ভবত তাদের কাছে স্পষ্ট হবে না। এমনকি আপনি যদি একা কাজ করছেন তবে আপনি এটি ভুলে যেতে পারেন এবং নিজেকে রাস্তায় অবাক করে দিতে পারেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.