# এক্সেপশন হ্যান্ডেলিং

আগের চ্যাপ্টারে আমরা দেখেছি, এক্সেপশন তৈরি হলে প্রোগ্রাম অনাকাঙ্ক্ষিত ভাবে বন্ধ হয়ে যায়। খুশির খবর হচ্ছে এরকম তৈরি হওয়া এক্সেপশন গুলোকে সঠিকভাবে হ্যান্ডেল করতে পারলে প্রোগ্রাম যেমন বন্ধ না হয়ে এগিয়ে চলবে তেমনি প্রোগ্রামের কোথায় কোন সমস্যা আছে সেগুলোকেও সহজে চিহ্নিত করা যাবে। এ জন্য পাইথনে আছে `try`, `except` স্টেটমেন্টের ব্যবহার।

`try` ব্লকের মধ্যে এমন কোড গুলো লেখা হয় যেখানে এক্সেপশন তৈরি হতে পারে (ইউজার ইনপুট বা সেরকম অন্যান্য কারনে)। আর `except` ব্লকের মধ্যে লেখা হয় এমন কোড যেগুলো এক্সিকিউট হবে যদি আসলেই ওই `try` ব্লকের মধ্যে কোন এক্সেপশন তৈরি হয়। অর্থাৎ `try` এর মধ্যে এক্সেপশন তৈরি হলে এই ব্লকের কোড এক্সিকিউশন বন্ধ হবে কিন্তু `except` ব্লকের কোড স্বাভাবিক ভাবে এক্সিকিউট হবে। একটি উদাহরণ দেখি -

```python
try:
    a = 1000
    b = int(input("Enter a divisor to divide 1000: "))
    print(a/b)
except ZeroDivisionError:
    print("You entered 0 which is not permitted!")
```

যদি ইনপুট হয় নিচের মত,

```python
Enter a divisor to divide 1000: 5
```

তাহলে আউটপুট,

```python
200.0
```

অথবা যদি ইনপুট হয় এরকম,

```python
Enter a divisor to divide 1000: 0
```

তবে আউটপুট,

```python
You entered 0 which is not permitted!
```

উপরের প্রোগ্রামে দুটো নাম্বার নিয়ে ভাগের কাজ করা হয়েছে। একটি নাম্বারের মান 1000 এবং আরেকটি নিচ্ছি ইউজারের কাছ থেকে। যদি ইউজার ভালোয় ভালোয় সঠিক সংখ্যা ইনপুট দেয় (যেমন 5) তাহলে প্রোগ্রামটি সঠিক ভাবে কাজ করে ভাগফল প্রিন্ট করছে। কিন্তু ইউজারের মনোভাব তো আমরা জানি না। ইউজার চাইলে শূন্য ইনপুট দিতে পারে। আর তখন প্রোগ্রাম ভাগ করতে না পেরে অনাকাঙ্ক্ষিত ভাবে বন্ধ হয়ে যাবে।

আর তাই সেটুকু আন্দাজ করেই আমরা ভাগ করার কোড টুকু একটি ট্রাই ব্লকের মধ্যে লিখেছি এবং সেই ব্লকের মধ্যে যদি শূন্য দিয়ে ভাগ করার কারনে কোন এক্সেপশন তৈরি হয় তাহলে সেটা হ্যান্ডেল করার জন্য এক্সেপ্ট ব্লক ব্যবহার করেছি এবং নির্দিষ্ট করে `ZeroDivisionError` এক্সেপশন হ্যান্ডেল করেছি। এখন, ইউজার চাইলে শূন্য ইনপুট দিতে পারে, তাই বলে প্রোগ্রাম অনাকাঙ্ক্ষিত ভাবে শাটডাউন বা বন্ধ হবে না। বরং ইউজারকে যথাযথ ম্যাসেজ দেখিয়ে স্বাভাবিক কাজ চালিয়ে যেতে পারছে।

একটি `try` ব্লকের সাপেক্ষে একাধিক `except` ব্লক থাকতে পারে। আবার একটি `except` এর জন্য একাধিক এক্সেপশন ডিফাইন করা যেতে পারে ব্র্যাকেট এবং কমা ব্যবহার করে। এতে করে ট্রাই ব্লকের মধ্যে বিভিন্ন রকম এক্সেপশনের জন্য বিভিন্ন এক্সেপ্ট ব্লক দিয়ে সঠিক ভাবে সমস্যাকে চিহ্নিত করা যায় এবং সে অনুযায়ী কাজ করা যায়। আরেকটি উদাহরণ দেখি -

```python
try:
    variable = 10
    print(variable + "hello")
    print(variable / 2)
except ZeroDivisionError:
    print("Divided by zero")
except (ValueError, TypeError):
    print("Type or value error occurred")
```

আউটপুট,

```python
Type or value error occurred
```

উপরের প্রোগ্রামে ট্রাই ব্লকে দুই রকম অঘটন ঘটতে পারে। `variable` কে `2` দিয়ে ভাগ না করে শূন্য দিয়ে ভাগ করা হতে পারতো এবং সেক্ষেত্রে `ZeroDivisionError` এক্সেপশন তৈরি হত। আবার ট্রাই ব্লকের দ্বিতীয় স্টেটমেন্ট যেখানে একটি ইন্টিজারের সাথে স্ট্রিং কে যোগ করে প্রিন্ট করার চেষ্টা করা হয়েছে, সেখানে। এই উদাহরণে এখানেই এক্সেপশন তৈরি হচ্ছে। আর তাই `TypeError` এক্সেপশন তৈরি হচ্ছে। কিন্তু আমরা সেটা সঠিকভাবে হ্যান্ডেল করেছি আর তাই প্রোগ্রাম হুট করে বন্ধ না হয়ে বরং সুন্দর ভাবে আমাদের নির্ধারিত একটি প্রিন্ট স্টেটমেন্ট `print("Type or value error occurred")` এক্সিকিউট করেছে।

চাইলে সুনির্দিষ্ট ভাবে কোন এক্সেপশন ডিফাইন না করেও `except` ব্লক ব্যবহার করা যাবে। সেক্ষেত্রে `try` ব্লকের মধ্যে ঘটে যাওয়া যেকোনো রকম এক্সেপশনের জন্য এই `except` ব্লক রান করবে। যেমন -

```python
try:
    word = "spam"
    print(word / 0)
except:
    print("An error occurred")
```

আউটপুট,

```python
An error occurred
```

বোঝাই যাচ্ছে `try` ব্লকের মধ্যে উল্টা পাল্টা টাইপের ডাটা নিয়ে ভাগ করার কোড লেখা হয়েছে। রান টাইমে এখানে অবশ্যই এক্সেপশন তৈরি হচ্ছে। আর তাই `except` ব্লক ব্যবহার করে হ্যান্ডেলও করা হয়েছে। আপাত দৃষ্টিতে বিষয়টি ভালো মনে হলেও এভাবে হ্যান্ডেল করা ব্লকের মাধ্যমে ট্রাই ব্লকে ঘটে যাওয়া অঘটনের সঠিক কারণ চিহ্নিত করা যাবে না।\
অর্থাৎ, ট্রাই ব্লকে যেকোনো রকম সমস্যার জন্যই এই এক্সেপ্ট ব্লক এক্সিকিউট হবে এবং বার বার শুধু `An error occurred` ম্যাসেজটাই ইউজারকে দেখানো হবে। কিন্তু যদি সম্ভাবনাময় কয়েকটি নির্দিষ্ট টাইপের এক্সেপ্ট ব্লক লিখে সেগুলোর মধ্যে আলাদা আলাদা ম্যাসেজ প্রিন্ট করা হত। তাহলে ইউজারকে আরও সুনির্দিষ্ট ম্যাসেজ দেয়া যেত এবং প্রোগ্রামটিকে পরবর্তীতে আপডেট করতেও সুবিধা হত।

> সংকলন - [নুহিল মেহেদী](https://nuhil.net)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://python.howtocode.dev/file-exception/exception-handling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
