ব্যবসায়িক অ্যাপের ত্রুটি শ্রেণীবিভাগ: সঙ্গতিপূর্ণ UI ও মনিটরিং
ব্যবসায়িক অ্যাপে ত্রুটি শ্রেণীবিভাগ ভ্যালিডেশন, প্রমাণীকরণ, রেট লিমিট ও ডিপেনডেন্সি ব্যর্থতাগুলো শ্রেণীবদ্ধ করতে সাহায্য করে যাতে UI ও মনিটরিং সঙ্গতিপূর্ণ থাকে।

একটি ত্রুটি ট্যাক্সোনমি বাস্তব ব্যবসায়িক অ্যাপে কী সমাধান করে
একটি ত্রুটি ট্যাক্সোনমি হল ত্রুটিগুলিকে নামকরণ ও গ্রুপ করার একটি সম্মিলিত উপায়, যাতে সবাই একইভাবে সেগুলো হ্যান্ডেল করে। প্রতিটি স্ক্রিন বা API আলাদা বার্তা তৈরি করার বদলে, আপনি কয়েকটি শ্রেণী (যেমন validation বা auth) এবং নির্দেশ নীতিমালা সংজ্ঞায়িত করেন যে কিভাবে সেগুলো ব্যবহারকারীর সামনে এবং মনিটরিং-এ প্রদর্শিত হবে।
যদি সেই সাধারণ কাঠামো না থাকে, একই সমস্যা বিভিন্ন রূপে দেখা দেয়। একটি প্রয়োজনীয় ফিল্ড অনুপস্থিত হলে মোবাইলে সেটা “Bad Request” দেখাতে পারে, ওয়েবে “কিছু ভুল হয়েছে” দেখা যায়, আর লগে স্ট্যাক ট্রেস থাকতে পারে। ব্যবহারকারীরা বুঝতে পারে না পরবর্তী কি করতে হবে, এবং অন-কলে থাকা টিম অনুমান করতে সময় নষ্ট করে যে এটি ব্যবহারকারীর ত্রুটি, আক্রমণ, না সার্ভিস আউটেজ।
লক্ষ্য হল সঙ্গতিপূর্ণতা: একই ধরনের ত্রুটি একই UI আচরণ ও একই অ্যালার্টিং আচরণ তৈরি করবে। ভ্যালিডেশন ইস্যুগুলো নির্দিষ্ট ফিল্ড নির্দেশ করবে। অনুমতি সমস্যা অ্যাকশন বন্ধ করবে এবং কি এক্সেস অনুপস্থিত তা ব্যাখ্যা করবে। অন্তর্নির্ভরতা ব্যর্থতা নিরাপদ রিট্রাই অফার করবে, আর মনিটরিং সঠিক টিমকে paging করবে।
বাস্তব উদাহরণ: একটি সেলস রিপ কাস্টমার রেকর্ড তৈরি করার চেষ্টা করে, কিন্তু পেমেন্ট সার্ভিস ডাউন। আপনার অ্যাপ যদি জেনেরিক 500 ফেরত দেয়, তারা পুনরায় চেষ্টা করবে এবং পরে ডুপ্লিকেট তৈরি হতে পারে। স্পষ্ট dependency-failure ক্যাটাগরি থাকলে UI বলবে সার্ভিস সাময়িকভাবে উপলব্ধ নয়, ডুপ্লিকেট সাবমিশন প্রতিহত করবে, এবং মনিটরিং সঠিক টিমকে জানান দেবে।
এই ধরনের সমন্বয় তখনই সবচেয়ে গুরুত্বপূর্ণ যখন এক ব্যাকএন্ড একাধিক ক্লায়েন্ট চালায়। যদি API, ওয়েব অ্যাপ, মোবাইল অ্যাপ এবং ইন্টারনাল টুল সব একই ক্যাটাগরি এবং কোড ব্যবহার করে, ব্যর্থতাগুলো র্যান্ডম মনে হওয়া বন্ধ করে।
একটি সহজ মডেল: category, code, message, details
ট্যাক্সোনমি রক্ষণাবেক্ষণযোগ্য থাকে যখন আপনি চারটি জিনিস আলাদা রাখেন যেগুলো প্রায়ই একসাথে মিশে যায়: ক্যাটাগরি (প্রশ্ন — সমস্যা কিসের 종류), কোড (একটি স্থিতিশীল শনাক্তকারী), মেসেজ (মানব-পাঠ্য), এবং ডিটেইলস (স্ট্রাকচার্ড কন্টেক্সট)। HTTP স্ট্যাটাস এখনও গুরুত্বপূর্ণ, কিন্তু এটি পুরো কাহিনি হওয়া উচিত না।
ক্যাটাগরি উত্তর দেয়: “UI এবং মনিটরিং কিভাবে আচরণ করবে?” একটি 403 এক জায়গায় “auth” বোঝাতে পারে, অন্য জায়গায় 403 হতে পারে “policy” যদি পরে নিয়ম যোগ করেন। ক্যাটাগরি আচরণের ব্যাপার—ট্রান্সপোর্ট নয়।
কোড উত্তর দেয়: “কতটা নির্দিষ্ট ঘটনা ঘটেছে?” কোডগুলো স্থিতিশীল ও সাধারণ হওয়া উচিত। যদি আপনি একটি বাটন নাম বদলান বা একটি সার্ভিস রিফ্যাক্টর করেন, কোড বদলানো উচিত না। ড্যাশবোর্ড, অ্যালার্ট, এবং সাপোর্ট স্ক্রিপ্ট এইগুলোর উপর নির্ভর করে।
মেসেজ উত্তর দেয়: “আমরা একজনকে কি বলব?” সিদ্ধান্ত নিন এই মেসেজ কার জন্য—ব্যবহারকারীর জন্য হলে সংক্ষিপ্ত ও সদয় হওয়া উচিত। সাপোর্ট মেসেজে পরবর্তী ধাপ থাকতে পারে। লগে বেশি টেকনিক্যাল হতে পারেন।
ডিটেইলস উত্তর দেয়: “আমরা এটা ঠিক করতে কি জানি?” ডিটেইলস স্ট্রাকচার্ড রাখুন যাতে UI প্রতিক্রিয়া দেখাতে পারে। একটি ফর্ম ত্রুটির ক্ষেত্রে তা হতে পারে ফিল্ড নাম। একটি dependency ইস্যুর ক্ষেত্রে upstream সার্ভিসের নাম ও retry-after মান হতে পারে।
অনেকে ব্যবহার করে এমন একটি কম্প্যাক্ট শেপ এখানে:
{
"category": "validation",
"code": "CUSTOMER_EMAIL_INVALID",
"message": "Enter a valid email address.",
"details": { "field": "email", "rule": "email" }
}
ফিচার বদলালে, ক্যাটাগরিগুলো ছোট ও স্থিতিশীল রাখুন, এবং পুরনো কোডগুলো পুনঃব্যবহার না করে নতুন কোড যোগ করুন। এতে UI আচরণ, মনিটরিং ট্রেন্ড, এবং সাপোর্ট প্লেবুক প্রোডাক্টের পরিবর্তনের সাথে নির্ভরযোগ্য থাকে।
প্রধান ক্যাটাগরি: validation, auth, rate limits, dependencies
অধিকাংশ ব্যবসায়িক অ্যাপ চারটি ক্যাটাগরির সাথে শুরু করতে পারে যা সর্বত্র দেখা যায়। যদি আপনি এগুলো ব্যাকএন্ড, ওয়েব, এবং মোবাইলে একইভাবে নামকরণ ও ট্রিট করেন, UI সঙ্গতভাবে প্রতিক্রিয়া দিতে পারবে এবং মনিটরিং পড়তে সুবিধা হবে।
Validation (expected)
ভ্যালিডেশন ত্রুটি ঘটে যখন ব্যবহারকারীর ইনপুট বা কোন ব্যবসায়িক নিয়ম ব্যর্থ হয়। এগুলো স্বাভাবিক এবং সহজে ঠিক করা উচিত: অনুপস্থিত প্রয়োজনীয় ফিল্ড, অবৈধ ফরম্যাট, বা নিয়ম যেমন “ডিসকাউন্ট 20% ছাড়াতে পারে না” বা “অর্ডার মোট অবশ্যই > $0”। UI-কে নির্দিষ্ট ফিল্ড বা নিয়ম হাইলাইট করতে হবে,_generic এলার্ট দেখানো উচিত নয়।
Authentication vs authorization (expected)
Auth ত্রুটিগুলো সাধারণত দুইটি কেসে বিভক্ত: not authenticated (লগ ইন নেই, সেশন মেয়াদ শেষ, টোকেন অনুপস্থিত) এবং not authorized (লগ ইন আছে, কিন্তু অনুমতি নেই)। এদের আলাদা করে ট্রিট করুন। প্রথম কেসে “দয়া করে আবার সাইন ইন করুন” মেসেজ মানায়। দ্বিতীয় কেসে সংবেদনশীল বিশদ প্রকাশ না করে স্পষ্ট থাকুন: “আপনার কাছে ইনভয়েস অনুমোদনের অ্যাক্সেস নেই।”
Rate limits (expected, but time-based)
রেট সীমা মানে “অনেক অনুরোধ হয়েছে, পরে চেষ্টা করুন।” এটি প্রায়ই ইম্পোর্ট, ব্যস্ত ড্যাশবোর্ড, বা বারবার রিট্রাই-র সময় ঘটে। একটি retry-after হিন্ট দিন (এটিও হতে পারে “৩০ সেকেন্ড অপেক্ষা করুন”) এবং UI-কে hammering করা বন্ধ করার জন্য ব্যাক অফ করান।
Dependency failures (often unexpected)
Dependency ব্যর্থতা আসে upstream সার্ভিস, টাইমআউট, বা আউটেজ থেকে: পেমেন্ট প্রোভাইডার, ইমেইল/এসএমএস, ডেটাবেস, বা অভ্যন্তরীণ সার্ভিস। ব্যবহারকারীরা এটা ঠিক করতে পারবে না, তাই UI একটি নিরাপদ ব্যাকফল (ড্রাফট সেভ করা, পরে চেষ্টা করা, সাপোর্ট-এ যোগাযোগ) অফার করা উচিত।
মূল পার্থক্য হচ্ছে আচরণ: প্রত্যাশিত ত্রুটিগুলো সাধারণ ফ্লো-এর অংশ এবং সঠিক প্রতিক্রিয়া পাওয়া উচিত; অপ্রত্যাশিত ত্রুটিগুলো স্থিতিশীলতার সংকেত এবং অ্যালার্ট, correlation IDs, এবং যত্নসহকারে লগিং ট্রিগার করা উচিত।
ধাপে ধাপে: এক ওয়ার্কশপে আপনার ট্যাক্সোনমি তৈরি করুন
ট্যাক্সোনমি এমন হওয়া উচিত যে মানুষ মনে রাখতে পারে, কিন্তু কঠোর যে দুইটি টিম একই সমস্যাকে একভাবে লেবেল করবে।
১) সময়সীমা নির্ধারণ করে ছোট একটি সেট বেছে নিন
৬০ থেকে ৯০ মিনিটের একটি ওয়ার্কশপ দিয়ে শুরু করুন। সবচেয়ে বেশি দেখা ত্রুটিগুলোর তালিকা করুন (খারাপ ইনপুট, লগইন সমস্যা, অতিরিক্ত অনুরোধ, তৃতীয়-পক্ষ আউটেজ, অনাকাঙ্খিত বাগ), তারপর সেগুলোকে ৬ থেকে ১২ ক্যাটাগরিতে কনসোলিডেট করুন যাতে সবাই ডক না দেখে মুখস্ত বলতেই পারে।
২) স্থায়ী কোড স্কিমে সম্মত হন
একটি নামকরণ প্যাটার্ন বেছে নিন যা লগ ও টিকেটে পাঠযোগ্য থাকে। সংক্ষিপ্ত রাখুন, ভার্সন নম্বর এড়িয়ে চলুন, এবং কোডগুলো রিলিজের পর স্থায়ী হিসেবে বিবেচিত করুন। একটি সাধারণ প্যাটার্ন হল ক্যাটাগরি প্রিফিক্স প্লাস ক্লিয়ার স্লাগ, যেমন AUTH_INVALID_TOKEN বা DEP_PAYMENT_TIMEOUT।
রুম ছাড়ার আগে সিদ্ধান্ত নিন প্রতিটি ত্রুটিতে কি অন্তত থাকবে: ক্যাটাগরি, কোড, নিরাপদ মেসেজ, স্ট্রাকচার্ড ডিটেইলস, এবং একটি ট্রেস বা রিকোয়েস্ট ID।
৩) ক্যাটাগরি বনাম কোডের জন্য একটি নিয়ম লেখুন
যখন ক্যাটাগরিগুলো ডাম্পিং গ্রাউন্ড হয়ে ওঠে টিমগুলো আটকে যায়। একটি সহজ নিয়ম সাহায্য করে: ক্যাটাগরি উত্তর দেয় “UI ও মনিটরিং কিভাবে প্রতিক্রিয়া দেখাবে?”, কোড উত্তর দেয় “নির্দিষ্টভাবে কি ঘটল?”। যদি দুইটি ব্যর্থতার জন্য ভিন্ন UI আচরণ দরকার হয়, সেগুলো একই ক্যাটাগরি শেয়ার করা উচিত নয়।
৪) প্রতিটি ক্যাটাগরির জন্য ডিফল্ট UI আচরণ নির্ধারণ করুন
ডিফল্টভাবে ব্যবহারকারী কি দেখবে তা নির্ধারণ করুন। ভ্যালিডেশন ফিল্ডগুলিকে হাইলাইট করবে। Auth সাইন-ইন পাঠাবে বা অ্যাক্সেস মেসেজ দেখাবে। রেট লিমিট “X সেকেন্ড পরে চেষ্টা করুন” দেখাবে। dependency ব্যর্থতা একটি শান্ত রিট্রাই স্ক্রিন দেখাবে। এই ডিফল্টগুলি থাকলে নতুন ফিচারগুলো সেগুলো অনুসরণ করবে এবং ওয়ান-অফ হ্যান্ডলিং তৈরি হবে না।
৫) বাস্তব সিনারিও দিয়ে পরীক্ষা করুন
পাঁচটি সাধারণ ফ্লো (সাইনআপ, চেকআউট, সার্চ, অ্যাডমিন এডিট, ফাইল আপলোড) চালান এবং প্রতিটি ব্যর্থতা লেবেল করুন। যদি দল বিতর্ক করে, সাধারণত একটি পরিষ্কার নিয়ম দরকার, নতুন ২০টি কোড নয়।
Validation ত্রুটি: ব্যবহারকারীদের জন্য কার্যকর করে তুলুন
ভ্যালিডেশন হল একমাত্র ত্রুটি ধরণ যা আপনি সাধারণত তাৎক্ষণিকভাবে দেখাতে চান। এটি পূর্বানুমানযোগ্য হওয়া উচিত: ব্যবহারকারী কি ঠিক করতে হবে তা বলে এবং এটি কখনই রিট্রাই লুপ ট্রিগার করবে না।
ফিল্ড-লেভেল এবং ফর্ম-লেভেল ভ্যালিডেশন আলাদা সমস্যা। ফিল্ড-লেভেল ত্রুটি একটি ইনপুটের সাথে ম্যাচ করে (ইমেইল, ফোন, পরিমাণ)। ফর্ম-লেভেল ত্রুটি হচ্ছে ইনপুটগুলোর সংমিশ্রণ সম্পর্কিত (শুরু তারিখ অবশ্যই শেষ তারিখের আগে থাকতে হবে) বা প্রয়োজনীয়তা অনুপস্থিত (কোনও শিপিং মেথড নির্বাচিত নেই)। আপনার API রেসপন্স এই পার্থক্য পরিষ্কার করে দিন যাতে UI সঠিকভাবে প্রতিক্রিয়া দেখাতে পারে।
একটি সাধারণ ব্যবসায়িক নিয়ম বিচ্যুতি হল “ক্রেডিট লিমিট অতিক্রম করেছে।” ব্যবহারকারী হয়তো ভ্যালিড নম্বর দিয়েছে, কিন্তু অ্যাকশন অ্যাকাউন্ট স্টেটের কারণে অনুমোদিত নয়। এটিকে ফর্ম-লেভেল ভ্যালিডেশন ত্রুটি হিসেবে ট্রিট করুন এবং একটি স্পষ্ট কারণ ও নিরাপদ হিন্ট দিন, যেমন “আপনার উপলব্ধ লিমিট $500। পরিমাণ কমান বা বৃদ্ধি অনুরোধ করুন।” ডাটাবেস ফিল্ড, স্কোরিং মডেল বা রুল ইঞ্জিন স্টেপের অভ্যন্তরীণ নাম প্রকাশ করা এড়ান।
একটি কার্যকর রেসপন্স সাধারণত অন্তর্ভুক্ত করে একটি স্থিতিশীল কোড (শুধু ইংরেজি বাক্য নয়), ব্যবহারকারী-উপযোগী মেসেজ, বিকল্পে ফিল্ড পয়েন্টার ফিল্ড-লেভেল ইস্যুর জন্য, এবং ছোট নিরাপদ হিন্ট (ফরম্যাট উদাহরণ, অনুমোদিত রেঞ্জ)। যদি ইঞ্জিনিয়ারদের জন্য একটি রুল নাম দরকার হয়, তা লগে রাখুন, UI-তে নয়।
ভ্যালিডেশন ব্যর্থতাগুলোকে সিস্টেম-ত্রুটির থেকে আলাদা করে লগ করুন। প্যাটার্ন ডিবাগের জন্য পর্যাপ্ত কনটেক্সট রাখুন কিন্তু সংবেদনশীল ডেটা সংরক্ষণ করবেন না। ইউজার আইডি, রিকোয়েস্ট ID, রুল নাম বা কোড এবং কোন ফিল্ড ফেল করেছে তা রেকর্ড করুন। ভ্যালু জন্য সাধারণত যা দরকার (উপস্থিত/অনুপস্থিত বা দৈর্ঘ্য) ছাড়া লগে সংবেদনশীল ডেটা মাস্ক করুন।
UI-তে ফোকাস করুন ঠিক করার উপর, রিট্রাই করার উপর নয়। ফিল্ডগুলো হাইলাইট করুন, ব্যবহারকারী যা টাইপ করেছে তা রাখুন, প্রথম ত্রুটিতে স্ক্রল করুন, এবং স্বয়ংক্রিয় রিট্রাই নিষ্ক্রিয় করুন। ভ্যালিডেশন ত্রুটিগুলো সাময়িক নয়, তাই “আবার চেষ্টা করুন” সময় নষ্ট।
Auth এবং অনুমতি ত্রুটি: সুরক্ষা ও স্পষ্টতা বজায় রাখুন
Authentication এবং authorization ব্যর্থতাগুলো ব্যবহারকারীদের কাছে দেখতে অনুরূপ মনে হতে পারে, কিন্তু সেগুলো সিকিউরিটি, UI ফ্লো, এবং মনিটরিং-এর জন্য ভিন্ন অর্থ বহন করে। সেগুলো আলাদা রাখলে ওয়েব, মোবাইল, ও API ক্লায়েন্ট জুড়ে আচরণ সঙ্গতিপূর্ণ হয়।
Unauthenticated মানে অ্যাপ ব্যবহারকারীর পরিচয় প্রমাণ করতে পারে না। সাধারণ কারণ হলো অনুপস্থিত ক্রেডেনশিয়াল, অবৈধ টোকেন, অথবা মেয়াদোত্তীর্ণ সেশন। Forbidden মানে ব্যবহারকারী পরিচিত, কিন্তু অ্যাকশন করার অনুমতি নেই।
সেশন মেয়াদোত্তীর্ণ সবচেয়ে সাধারণ এজ কেস। যদি আপনি refresh tokens সমর্থন করেন, একবার সাইলেন্ট রিফ্রেশ চেষ্টা করে দেখুন, তারপর মূল অনুরোধটি পুনরায় চেষ্টা করুন। যদি রিফ্রেশ ব্যর্থ হয়, একটি unauthenticated ত্রুটি ফেরত দিন এবং ব্যবহারকারীকে পুনরায় সাইন ইন করান। লুপ এড়ান: একবার রিফ্রেশ চেষ্টা করার পর থামুন এবং পরবর্তী স্পষ্ট ধাপ দেখান।
UI আচরণগুলো পূর্বানুমানীয় থাকা উচিত:
- Unauthenticated: সাইন-ইন প্রম্পট দিন এবং ব্যবহারকারী যা করার চেষ্টা করছিল তা সংরক্ষণ করুন
- Forbidden: পেজেই থাকুন এবং একটি এক্সেস মেসেজ দেখান, সঙ্গে একটি নিরাপদ অপশন দিন যেমন “অ্যাক্সেস অনুরোধ করুন”
- অ্যাকাউন্ট ডিজেবল বা প্রত্যাহার করা হয়েছে: সাইন আউট করুন এবং সংক্ষিপ্ত বার্তা দেখান যে সাপোর্ট সাহায্য করতে পারে
অডিটিংয়ের জন্য লগে যথেষ্ট তথ্য রাখুন যেন প্রশ্নের উত্তর দেয়া যায় “কে কি চেষ্টা করেছিল এবং কেন ব্লক করা হয়েছিল”—বিনা সিক্রেট প্রকাশ করে। একটি ব্যবহারযোগ্য রেকর্ডে থাকতে পারে ইউজার আইডি (যদি জানা থাকে), টেনান্ট বা ওয়ার্কস্পেস, অ্যাকশন নাম, রিসোর্স আইডেন্টিফায়ার, টাইমস্ট্যাম্প, রিকোয়েস্ট ID, এবং নীতি পরীক্ষার ফলাফল (allowed/denied)। কাঁচা টোকেন এবং পাসওয়ার্ড লগে রাখবেন না।
ব্যবহারকারী-সম্মুখীন মেসেজে রোল নাম, অনুমতির নিয়ম, বা অভ্যন্তরীণ নীতি কাঠামো প্রকাশ করবেন না। “আপনার কাছে ইনভয়েস অনুমোদনের অ্যাক্সেস নেই” বলাই নিরাপদ, “শুধুমাত্র FinanceAdmin ইনভয়েস অনুমোদন করতে পারে” বলার চেয়ে।
রেট লিমিট ত্রুটি: লোডের সময় পূর্বনির্ধারিত আচরণ
রেট লিমিট ত্রুটিগুলো বাগ নয়—এগুলো একটি সেফটি রেল। এগুলোকে প্রথম-শ্রেণীর ক্যাটাগরি হিসেবে ট্রিট করুন যাতে UI, লগ, এবং অ্যালার্ট কনসিস্টেন্টভাবে প্রতিক্রিয়া করে যখন ট্র্যাফিক লাফ দেয়।
রেট লিমিট সাধারণত কয়েকটি রূপ নেয়: per user (একজন ব্যক্তি খুব দ্রুত ক্লিক করছে), per IP (অফিস নেটওয়ার্কে অনেক ব্যবহারকারী), বা per API key (একটি ইন্টিগ্রেশন জব অপ্রয়োজনীয়ভাবে চলছে)। কারণ গুরুত্বপুর্ণ কারণ সমাধান আলাদা।
একটি ভালো rate-limit রেসপন্সে কী থাকা উচিত
ক্লায়েন্টদের দুটি জিনিস দরকার: তারা সীমাবদ্ধ এবং কখন আবার চেষ্টা করবে। HTTP 429 ফেরত দিন এবং একটি পরিষ্কার অপেক্ষা সময় দিন (উদাহরণস্বরূপ, Retry-After: 30)। এছাড়া একটি স্থিতিশীল ত্রুটি কোড দিন (যেমন RATE_LIMITED) যাতে ড্যাশবোর্ড ইভেন্টগুলো গ্রুপ করতে পারে।
মেসেজ শান্ত ও নির্দিষ্ট রাখুন। “Too many requests” সঠিক হলেও অনেক সময় সহায়ক নয়। “Please wait 30 seconds and try again” প্রত্যাশা সেট করে এবং বারবার ক্লিক কমায়।
UI পাশ থেকে দ্রুত পুনরায় চেষ্টা প্রতিরোধ করুন। একটি সহজ প্যাটার্ন হল অ্যাকশনটি অপেক্ষা সময়ের জন্য নিষ্ক্রিয় করা, একটি ছোট কাউন্টডাউন দেখানো, তারপর টাইমার শেষ হলে একটি নিরাপদ রিট্রাই দেওয়া। ব্যবহারকারীদের ধারণা দিন যে ডেটা হারায়নি।
মনিটরিং-এ টিমগুলো প্রায়ই অতিক্রিয়া করে। প্রতিটি 429-এ পেজ করবেন না। হার ট্র্যাক করুন এবং অস্বাভাবিক স্পাইকের উপর সতর্কতা রাখুন: কোনো এন্ডপয়েন্ট, টেন্যান্ট, বা API key-তে হঠাৎ লাফ কার্যকর পদক্ষেপ।
ব্যাকএন্ড আচরণও পূর্বনির্ধারিত হওয়া উচিত। স্বয়ংক্রিয় রিট্রাই-র জন্য exponential backoff ব্যবহার করুন, এবং রিট্রাইগুলো idempotent রাখুন। একটি “Create invoice” অ্যাকশন যদি প্রথম অনুরোধ সফল হয়ে থাকে, তাহলে সেকেন্ডবারের অনুরোধ দিয়ে দুটি ইনভয়েস তৈরি করা উচিত নয়।
Dependency ব্যর্থতা: অচেতন চালচলিকে ছাড়াই আউটেজ হ্যান্ডেল করুন
Dependency ব্যর্থতাগুলো হচ্ছে ব্যবহারকারী ঠিকঠাক কাজ করলেও ঘটে—পেমেন্ট গেটওয়ে টাইমআউট, ডেটাবেস কানেকশন ড্রপ, বা upstream সার্ভিস 5xx রিটার্ন। এগুলো আলাদা ক্যাটাগরি হিসেবে ট্রিট করুন যাতে UI ও মনিটরিং সঙ্গতভাবে আচরণ করে।
শুরুতে সাধারণ ব্যর্থতার ধরনগুলো নামকরণ করুন: টাইমআউট, কানেকশন ত্রুটি (DNS, TLS, refused), এবং upstream 5xx (bad gateway, service unavailable)। মূল কারণ জানা না থাকলেও আপনি কি ঘটেছে তা ক্যাপচার করে এবং সঙ্গত প্রতিক্রিয়া দেখাতে পারবেন।
Retry বনাম দ্রুত ব্যর্থ হওয়া
রিট্রাই ক্ষণিকের হিকআপের জন্য সাহায্য করে, কিন্তু এটি আউটেজ খারাপও করতে পারে। সহজ নিয়ম ব্যবহার করুন যাতে প্রত্যেক টিম একই সিদ্ধান্ত নেয়।
- যখন ত্রুটি সম্ভবত সাময়িক—টাইমআউট, কানেকশন রিসেট, 502/503—রিট্রাই করুন
- ব্যবহারকারী-সৃষ্ট বা স্থায়ী কেসে দ্রুত ব্যর্থ হন—dependency থেকে 4xx, অবৈধ ক্রেডেনশিয়াল, অনুপস্থিত রিসোর্স
- রিট্রাই সীমা দিন (উদাহরণ ২–৩ চেষ্টা) এবং ছোট ব্যাকঅফ যোগ করুন
- নন-আইডেমপোটেন্ট অ্যাকশনের জন্য কখনই রিট্রাই করবেন না যদি না idempotency key থাকে
UI আচরণ ও নিরাপদ ব্যাকফল
যখন একটি dependency ব্যর্থ হয়, ব্যবহারকারীকে বলুন পরবর্তী কি করা যাবে যাতে তাদের উপর দোষ চাপানো না হয়: “সাময়িক সমস্যা। দয়া করে পরে চেষ্টা করুন।” যদি একটি নিরাপদ ব্যাকফল থাকে, তা অফার করুন। উদাহরণ: Stripe ডাউন থাকলে ব্যবহারকারীকে “Pending payment” হিসেবে অর্ডার সেভ করার অপশন দিন এবং ইমেইল কনফার্মেশন পাঠান, যাতে কার্ট হারিয়ে না যায়।
একইভাবে ডাবল সাবমিট থেকে ব্যবহারকারীকে রক্ষা করুন। যদি ব্যবহারকারী “Pay” দুবার ট্যাপ করে ধীর প্রতিক্রিয়ার সময়, আপনার সিস্টেম এটাকে শনাক্ত করবে। Create-and-charge ফ্লোর জন্য idempotency keys ব্যবহার করুন, অথবা অ্যাকশন চালানোর আগে স্টেট চেক (যেমন “order already paid”) করুন।
মনিটরিং-এ লগ করুন এমন ফিল্ড যা দ্রুত উত্তর দেয়: “কোন dependency ব্যর্থ হচ্ছে এবং কতটা খারাপ?” dependency নাম, endpoint বা অপারেশন, সময়কাল, এবং চূড়ান্ত ফলাফল (timeout, connect, upstream 5xx) ক্যাপচার করুন। এটি অ্যালার্ট ও ড্যাশবোর্ডকে শব্দহীন না করে অর্থপূর্ণ করে তোলে।
চ্যানেল জুড়ে মনিটরিং ও UI সঙ্গতিপূর্ণ করুন
ট্যাক্সোনমি তখনই কাজ করে যখন প্রতিটি চ্যানেল একই ভাষা বলে: API, ওয়েব UI, মোবাইল অ্যাপ, এবং আপনার লগ। না হলে একই সমস্যা পাঁচটি ভিন্ন মেসেজ হিসেবে দেখা যায়, এবং কেউই জানে না এটি ব্যবহারকারী ত্রুটি নাকি বাস্তব আউটেজ।
HTTP স্ট্যাটাস কোডগুলোকে সেকেন্ডারি লেয়ার হিসেবে বিবেচনা করুন। এগুলো প্রোক্সি ও বেসিক ক্লায়েন্ট আচরণে সাহায্য করে, কিন্তু আপনার ক্যাটাগরি ও কোড প্রকৃত অর্থ বহন করবে। একটি dependency timeout এখনও 503 হতে পারে, কিন্তু ক্যাটাগরি UI-কে “পুনরায় চেষ্টা করুন” অফার করতে বলবে এবং মনিটরিং-কে অন-কলে নোটিফাই করবে।
প্রতিটি API-কে একটি স্ট্যান্ডার্ড ত্রুটি শেপ ফেরত দেওয়ার বিষয়টি সম্মত করুন, যদিও উৎস আলাদা (ডেটাবেস, auth মডিউল, থার্ড-পার্টি API)। একটি সহজ শেপ UI হ্যান্ডলিং এবং ড্যাশবোর্ড কনসিস্টেন্ট রাখতে সাহায্য করে:
{
"category": "dependency",
"code": "PAYMENTS_TIMEOUT",
"message": "Payment service is not responding.",
"details": {"provider": "stripe"},
"correlation_id": "9f2c2c3a-6a2b-4a0a-9e9d-0b0c0c8b2b10"
}
Correlation ID হলো “একজন ব্যবহারকারী একটি ত্রুটি দেখেছে” এবং “আমরা এটি ট্রেস করতে পারি” এর মধ্যে সেতুবন্ধন। UI-তে correlation_id দেখান (কপি বোতাম সাহায্য করে), এবং প্রতিটি সার্ভিসে এটি লগ করুন যাতে এক অনুরোধ সার্ভিস জুড়ে ট্রেস করা যায়।
UI-তে কি দেখানো নিরাপদ আর কি শুধু লগে রাখা হবে সেইটা সম্মত করুন। একটি বাস্তবসম্মত বিভাজন হল: UI পায় ক্যাটাগরি, একটি পরিষ্কার মেসেজ, এবং পরবর্তী ধাপ; লগ পায় টেকনিক্যাল ত্রুটি বিবরণ ও অনুরোধ কনটেক্সট; উভয়ই শেয়ার করে correlation_id ও স্থিতিশীল ত্রুটি কোড।
সঙ্গতিপূর্ণ ত্রুটি সিস্টেমের দ্রুত চেকলিস্ট
সঙ্গতিপূর্ণতা ভালো রকম বিরক্তিকর—প্রতিটি চ্যানেল একইভাবে আচরণ করে, এবং মনিটরিং সত্য বলে।
প্রথমে ব্যাকএন্ড চেক করুন, ব্যাকগ্রাউন্ড জব এবং ওয়েবহুকসহ। যদি কোনো ফিল্ড ঐচ্ছিক রাখেন, মানুষ সেটি স্কিপ করবে এবং সঙ্গতিপূর্ণতা ভেঙে পড়বে।
- প্রতিটি ত্রুটিতে ক্যাটাগরি, স্থায়ী কোড, ব্যবহারকারী-নিরাপদ মেসেজ, এবং একটি ট্রেস ID থাকবে।
- ভ্যালিডেশন সমস্যা প্রত্যাশিত, তাই তারা paging অ্যালার্ট ট্রিগার করবে না।
- Auth ও অনুমতি ইস্যুগুলো সিকিউরিটি প্যাটার্ন হিসেবে ট্র্যাক করা হবে, কিন্তু আউটেজের মতো আচরণ করবে না।
- রেট লিমিট রেসপন্সে একটি retry হিন্ট (উদাহরণস্বরূপ, অপেক্ষা করার সেকেন্ড) থাকবে এবং অ্যালার্ট স্প্যাম করবে না।
- Dependency ব্যর্থতায় dependency নাম ও টাইমআউট বা স্ট্যাটাস ডিটেইলস থাকবে।
তারপর UI নিয়মগুলো চেক করুন। প্রতিটি ক্যাটাগরি একটি পূর্বানুমানীয় স্ক্রিন আচরণে ম্যাপ করা উচিত যাতে ব্যবহারকারীরা পরবর্তী কি করতে হবে ভেবে না তাকায়: validation ফিল্ডগুলো হাইলাইট করবে, auth সাইন-ইন প্রম্পট করবে বা অ্যাক্সেস দেখাবে, rate limits শান্তভাবে অপেক্ষা দেখাবে, dependency ব্যর্থতা রিট্রাই ও ব্যাকফল অফার করবে।
একটি সহজ টেস্ট হল staging-এ প্রতিটি ক্যাটাগরি থেকে একটি ত্রুটি ট্রিগার করে ওয়েব অ্যাপ, মোবাইল অ্যাপ, ও অ্যাডমিন প্যানেলে একই ফলাফল নিশ্চিত করা।
সাধারণ ভুল ও বাস্তবসম্মত পরবর্তী ধাপ
ত্রুটি সিস্টেমকে পরে করার নজির সবচেয়ে দ্রুত এটি ভাঙে। বিভিন্ন টিম একই সমস্যার জন্য ভিন্ন শব্দ, ভিন্ন কোড, এবং ভিন্ন UI আচরণ ব্যবহার করে। ট্যাক্সোনমি কাজ করে যখন এটি ধারাবাহিক থাকে।
সাধারণ ব্যর্থতা প্যাটার্নসমূহ:
- অভ্যন্তরীণ এক্সসেপশন টেক্সট ব্যবহারকারীর কাছে লিক করে দেওয়া। এটা মানুষকে বিভ্রান্ত করে এবং সংবেদনশীল বিবরণ প্রকাশ করতে পারে।
- প্রতিটি 4xx-কে “validation” বলা। অনুপস্থিত অনুমতি একটি ফিল্ড অনুপস্থিত হওয়ার সমান নয়।
- প্রতিটি ফিচারের জন্য নতুন কোড আবিষ্কার করা বিনা রিভিউয়ের—শেষে ২০০টি কোড হয়ে যায় যা একই ৫টি জিনিস বোঝায়।
- ভুল ত্রুটির উপর রিট্রাই করা। অনুমতি ত্রুটি বা ভুল ইমেইলের উপর রিট্রাই কেবল শব্দ তৈরি করে।
সরল উদাহরণ: একটি সেলস রিপ “Create customer” ফর্ম জমা দেয় এবং 403 পায়। যদি UI সব 4xx-কে ভ্যালিডেশন হিসেবে ট্রীট করে, এটি এলোমেলো ফিল্ড হাইলাইট করবে এবং তাদের “ইনপুট ঠিক করুন” বলবে, অথচ আসল সমস্যা হলো তারা রোল নেই। মনিটরিং তখন ভ্যালিডেশন ইস্যুতে স্পাইক দেখাবে যেখানে প্রকৃত সমস্যা রোল কনফিগারেশন।
সংক্ষিপ্ত ওয়ার্কশপে ফিট করার বাস্তবসম্মত পরবর্তী ধাপ: এক পেজের ট্যাক্সোনমি ডক (ক্যাটাগরি, কখন ব্যবহার করতে হবে, ৫–১০টি ক্যানোনিকাল কোড), মেসেজ নীতি নির্ধারণ (UI-তে কি দেখবে বনাম লগে কি যায়), নতুন কোডগুলোর জন্য একটি হালকা রিভিউ গেট, প্রতিটি ক্যাটাগরির জন্য রিট্রাই নিয়ম নির্ধারণ, তারপর end-to-end ইমপ্লিমেন্ট (ব্যাকএন্ড রেসপন্স, UI ম্যাপিং, এবং মনিটরিং ড্যাশবোর্ড)।
If you’re building with AppMaster (appmaster.io), it helps to centralize these rules in one place so the same category and code behavior carries across the backend, web app, and native mobile apps.
প্রশ্নোত্তর
যখন একই ব্যাকএন্ড একাধিক ক্লায়েন্ট (ওয়েব, মোবাইল, ইন্টারনাল টুল) সার্ভ করে, বা যখন সাপোর্ট ও অন-কলে বার বার প্রশ্ন আসে “এটি ব্যবহারকারী ত্রুটি নাকি সিস্টেম সমস্যা?”, তখন ট্যাক্সোনমি তৈরি করা উচিত। পুনরাবৃত্ত ফ্লো যেমন সাইনআপ, চেকআউট, ইমপোর্ট বা অ্যাডমিন এডিট থাকলেই এটি দ্রুতই উপকারি হবে।
শুরু করার জন্য ৬–১২টি ক্যাটাগরি ভালো—এগুলো মানুষ মেমরিতে রাখতে পারে בלי ডক পড়া। ক্যাটাগরি গুলো বিস্তৃত এবং স্থিতিশীল রাখুন (validation, auth, rate_limit, dependency, conflict, internal ইত্যাদি), আর নির্দিষ্ট পরিস্থিতি দেখাতে কোড ব্যবহার করুন।
ক্যাটাগরি আচরণ নির্ধারণ করে—UI ও মনিটরিং কী করবে—আর কোড ঠিক কোন পরিস্থিতি ঘটেছে তা নির্ধারণ করে। ক্যাটাগরি বলে ‘কি করা উচিত’, কোড বলে ‘কি ঘটেছে’ এবং কোড স্থিতিশীল থেকে ড্যাশবোর্ড ও অটোমেশন কাজ করবে।
ম্যাসেজকে পরিচয়কারী হিসেবে ব্যবহার করবেন না। UI-র জন্য সংক্ষিপ্ত, ব্যবহারকারী-সুরক্ষিত টেক্সট ফেরত দিন, এবং গ্রুপিং ও অটোমেশনের জন্য স্থায়ী কোড ব্যবহার করুন। টেকনিক্যাল শব্দ দরকার হলে তা লগে রাখুন এবং একই correlation ID-তে যুক্ত করুন।
প্রতিটি API ত্রুটি রেসপন্সে অন্তর্ভুক্ত করুন: ক্যাটাগরি, স্থায়ী কোড, ব্যবহারকারী-সুরক্ষিত সংক্ষিপ্ত ম্যাসেজ, কনট্রোল-যোগ্য স্ট্রাকচার্ড ডিটেইলস, এবং একটি correlation বা request ID। ডিটেইলস এমন হতে হবে যাতে ক্লায়েন্ট ব্যবস্থা নিতে পারে—যেমন কোন ফিল্ড ফেল করেছে বা কত সেকেন্ড অপেক্ষা করতে হবে—কিন্তু র' ডাম্প করা এক্সসেপশন টেক্সট নয়।
ফিল্ড-লেভেল পয়েন্টার দিন যাতে UI সঠিক ইনপুট হাইলাইট করতে পারে এবং ব্যবহারকারী যা টাইপ করেছে তা রাখা যায়। ফর্ম-লেভেল ত্রুটি আলাদা রাখুন যখন সমস্যা ইনপুটগুলোর সংমিশ্রণের কারণে। এটি UI-কে ভুল ফিল্ড অনুমান করা থেকে রক্ষা করে।
Unauthenticated হলে UI-কে সাইন ইন পাঠান এবং ব্যবহারকারীর কাজটি রক্ষা করুন। Forbidden হলে একই পেজে রেখে একটি অ্যাক্সেস মেসেজ দেখান, কিন্তু রোল বা নীতির অভ্যন্তরীণ বিবরণ প্রকাশ করবেন না।
একটা স্পষ্ট অপেক্ষা সময় (উদাহরণ: retry-after ভ্যালু) ফেরত দিন এবং কোড স্থায়ী রাখুন যাতে ক্লায়েন্ট ব্যাকঅফ কনসিস্টেন্টভাবে ইমপ্লিমেন্ট করতে পারে। UI-তে দ্রুত পুনরায় ক্লিক বন্ধ করে একটি পরামর্শ দিন—কারণ দ্রুত পুনরায় চেষ্টা রেট-লিমিট আরও খারাপ করে।
শুধু তখনই রিট্রাই করুন যখন ত্রুটি সম্ভবত সাময়িক (টাইমআউট, কানেকশন রিসেট, upstream 502/503)। রিট্রাই সীমিত রাখুন, ব্যাকঅফ ব্যবহার করুন, এবং নন-আইডেমপোটেন্ট অ্যাকশনের জন্য idempotency key বা স্টেট চেক বাধ্য করুন; না হলে ডুপ্লিকেট তৈরি হতে পারে।
Correlation ID ব্যবহার করে ইউজারকে ওই আইডি দেখান (সাপোর্ট চাইলে তারা তা জানতে চাইবে) এবং সার্ভার-সাইডে এটিকে লগ করুন কোড ও গুরুত্বপূর্ণ কনটেক্সট সহ। এটা একটি ত্রুটির ইস্যু সার্ভিস জুড়ে ট্রেস করতে দেয়। AppMaster প্রজেক্টে এই শেপ এক জায়গায় কেন্দ্রীভূত করলে ব্যাকএন্ড, ওয়েব এবং মোবাইল আচরণ সমন্বিত হয়।


