Python-এ error handling ও logging: পরিষ্কারভাবে ব্যর্থ হোন
নির্দিষ্ট error ধরুন, নিজের exception-এ মুড়ুন ও কী ঘটেছে log করুন। exception chaining ও log level-সহ পরীক্ষিত উদাহরণ।

প্রোগ্রাম ব্যর্থ হয়: ফাইল হারায়, নেটওয়ার্ক পড়ে যায়, input ভুল হয়। ভালো error handling ঠিক করে তখন প্রোগ্রাম কী করবে, আর ভালো logging লেখে কী ঘটেছিল যাতে পরে সারানো যায়। নিচের code ও output প্রকাশের আগে Python 3-এ চালানো।
exception-এর নিয়ম
- নির্দিষ্ট error ধরুন, সব নয়।
except FileNotFoundErrorপরিষ্কার;except Exceptionbug লুকায়, আর খালিexcept:Ctrl+C-ও ধরে। - যেখানে কাজের কিছু করতে পারেন সেখানে ধরুন: আবার চেষ্টা, default ব্যবহার, বার্তা দেখানো। নইলে ওপরে যেতে দিন।
- নিম্নস্তরের error নিজের exception-এ মুড়ুন
raise ... from eদিয়ে। caller অর্থবহ error পায়, আর আসলটি কারণ হিসেবে থাকে। except: passদিয়ে কখনও error চুপ করাবেন না।withদিয়ে পরিষ্কার করুন (ফাইল, lock, connection), কিছু ব্যর্থ হলেও resource বন্ধ হয়।
log level
| Level | কীসের জন্য |
|---|---|
| DEBUG | ডেভেলপারের খুঁটিনাটি, production-এ বন্ধ |
| INFO | স্বাভাবিক ঘটনা (সেবা চালু হলো) |
| WARNING | অদ্ভুত কিছু, তবে চলেছে |
| ERROR | একটি কাজ ব্যর্থ |
| CRITICAL | প্রোগ্রাম আর চলতে পারে না |
start-up-এ একবার level ঠিক করুন। তার নিচের বার্তা বাদ পড়ে।
পরীক্ষিত উদাহরণ
import json, logging, sys
class ConfigError(Exception):
"""Raised when the configuration file is unusable."""
def load_config(path):
try:
with open(path) as f:
return json.load(f)
except FileNotFoundError as e:
raise ConfigError(f"config file not found: {path}") from e
except json.JSONDecodeError as e:
raise ConfigError(f"config is not valid JSON: {e.msg} at line {e.lineno}") from e
logging.basicConfig(stream=sys.stdout, level=logging.INFO, format="%(levelname)s %(name)s: %(message)s")
log = logging.getLogger("app")
def main(path):
try:
cfg = load_config(path)
except ConfigError as e:
log.error("cannot start: %s", e)
log.debug("this debug line is hidden at INFO level")
return 1
log.info("started with %d settings", len(cfg))
return 0
def risky():
try:
1 / 0
except ZeroDivisionError:
log.exception("calculation failed") # logs the message and the traceback
INFO app: started with 2 settings
exit 0
ERROR app: cannot start: config is not valid JSON: Illegal trailing comma before end of object at line 1
exit 1
ERROR app: cannot start: config file not found: missing.json
exit 1
ERROR app: calculation failed
Traceback (most recent call last):
File "app.py", line 30, in risky
1 / 0
~~^~~
ZeroDivisionError: division by zero
কী ঘটল:
- ভালো ফাইল স্বাভাবিকভাবে চালু হয়ে INFO-তে log করেছে।
- খারাপ ও হারানো ফাইল দুটোই একটি পরিষ্কার
ConfigErrorহয়েছে, যা এক জায়গায় ধরে ERROR log ও exit code ফেরানো হয়। - DEBUG লাইন আসেনি, কারণ level INFO ছিল।
exceptব্লকের ভেতরেlog.exceptionবার্তা ও traceback লিখেছে।
ভালো logging-এর অভ্যাস
- প্রসঙ্গসহ ঘটনা log করুন: order id, user id, ফাইলের নাম। শুধু "ব্যর্থ" কাজে লাগে না।
- lazy formatting ব্যবহার করুন,
log.error("cannot start: %s", e), string জোড়া নয়। - গোপন কিছু log করবেন না: পাসওয়ার্ড, token, কার্ড নম্বর বা পুরো ব্যক্তিগত তথ্য।
- error একবার log করুন, যেখানে সামলানো হয়, প্রতি স্তরে নয়।
- container-এ log standard output-এ পাঠান, প্ল্যাটফর্মকে জড়ো করতে দিন।
সাধারণ ভুল
except Exception: pass, বা এত বড় করে ধরা যে আসল bug মিলিয়ে যায়।- error-এর জন্য
Noneবা-1ফেরানো, যা caller যাচাই করতে ভুলবে। - প্রতি স্তরে log করে আবার raise, একই error দশবার তৈরি।
- একটি
tryব্লকে অনেক কিছু রাখা, ফলে কোন লাইন ব্যর্থ বোঝা যায় না। - সেবায় diagnostic-এ
print। level, timestamp ও routing হারান।
মূল কথা: যেখানে কাজ করতে পারেন সেখানে নির্দিষ্ট exception ধরুন, raise ... from দিয়ে মুড়ুন, আর সঠিক level ও যথেষ্ট প্রসঙ্গসহ log করুন, traceback-এর জন্য log.exception সহ।
Programming roadmaps সিরিজ, পর্ব ৩ (ভালো Python লেখা): 4 নম্বর (মোট 5)। আগের লেখা: Python-এ async/await: asyncio সময়সহ ব্যাখ্যা.


