FA-TOOLS — Header Component

مدیریت خطا در پایتون — try except

برنامه‌نویسی، رفیقِ برنامه‌نویس، همیشه همونطور که ما فکر می‌کنیم پیش نمیره. خطاها بخش جدانشدنی این ماجرا هستن؛ از اشتباهات تایپی ساده گرفته تا مشکلات پیچیده منطقی یا حتی خرابی‌های ناگهانی سرویس‌ها. اگه دنبال ابزارهای حرفه‌ای برنامه‌نویسی یا اسنیپت‌های آماده‌ای هستی که کارتو راه بندازه، یه سر به **فروشگاه ابزارهای برنامه‌نویسی fa-tools.ir** بزن. کلی کد آماده و راهکار کاربردی داریم که حتماً به دردت می‌خوره. می‌تونی همین الان هم با شماره **09202232789** تماس بگیری و مشورت کنی. حالا بریم سراغ یکی از حیاتی‌ترین مهارت‌ها برای هر پایتون‌کار: مدیریت خطا با `try except`.

🗺️ نقشه راه مدیریت خطا در پایتون (یک نگاه کلی)

مدیریت خطا در پایتون — try except با مثال کامل — تصویر 1

یه خلاصه‌ی مفید از کل بحثمون که سریع متوجه شی چی تو چنته داریم:

مفهوم کلیدی کاربرد اصلی
try کدی که ممکنه خطا بده رو داخلش می‌نویسیم.
except وقتی خطا رخ داد، اینجا می‌دونیم چطور باهاش برخورد کنیم.
except SpecificError خطاهای خاص رو شناسایی و مدیریت می‌کنیم.
except Exception as e همه خطاها رو می‌گیره (با احتیاط استفاده کن).
else اگه تو `try` هیچ خطایی نبود، این بلاک اجرا میشه.
finally این بلاک همیشه اجرا میشه، چه خطا باشه چه نباشه. (برای پاکسازی منابع)
استثنائات سفارشی تعریف خطاهای اختصاصی برای اپلیکیشن خودت.

هدف: برنامه‌های پایدارتر، تجربه کاربری بهتر، و عیب‌یابی راحت‌تر. ✨

چرا اصلاً باید خطاها رو مدیریت کنیم؟

مدیریت خطا در پایتون — try except با مثال کامل — تصویر 2

فرض کن یه کد نوشتی که باید دو تا عدد رو از کاربر بگیره و تقسیم کنه. حالا اگه کاربر به جای عدد، متن وارد کنه یا عدد دوم رو صفر بده چی میشه؟ برنامه‌ت با یه خطای زشت از کار می‌افته و شاید حتی کاربر رو هم کلافه کنه. مدیریت خطا یعنی پیش‌بینی اینجور سناریوها و آماده بودن برای برخورد مناسب باهاشون. این کار به چند دلیل خیلی مهمه:

  • پایداری برنامه: جلوی کرش کردن برنامه‌ت رو می‌گیره.
  • تجربه کاربری بهتر: به جای پیغام خطای سیستم، یه پیغام دوستانه و قابل فهم به کاربر نشون میده.
  • امنیت: گاهی اوقات خطاهای کنترل نشده می‌تونن اطلاعات حساسی از برنامه‌ت رو لو بدن.
  • اشکال‌زدایی راحت‌تر: با مدیریت صحیح، می‌تونی دقیقاً بفهمی مشکل از کجا بوده.

هدف اینه که برنامه‌ی تو مثل یه ماشین باکیفیت باشه که حتی وقتی یه مشکل کوچیک هم پیش میاد، چراغ‌های هشدارش روشن بشن و از کار نیفته.

ساختار اصلی: try و except

مدیریت خطا در پایتون — try except با مثال کامل — تصویر 3

هسته‌ی اصلی مدیریت خطا در پایتون، بلاک `try` و `except` هست. خیلی ساده بگم، کدی که فکر می‌کنی ممکنه خطا بده رو می‌ذاری تو بلاک `try`، و اگه خطایی رخ داد، کد داخل بلاک `except` اجرا میشه.

مثال ساده: تقسیم بر صفر

اینجا یه نمونه‌ی کلاسیک رو برات میارم: تقسیم یه عدد بر صفر.

🔗 کپی کد

try:
    result = 10 / 0
    print(result)
except ZeroDivisionError:
    print("نمی‌تونی یه عدد رو بر صفر تقسیم کنی، رفیق!")

خروجی:

نمی‌تونی یه عدد رو بر صفر تقسیم کنی، رفیق!

توضیح:
* داخل `try`، پایتون سعی می‌کنه `10 / 0` رو اجرا کنه.
* چون این کار منجر به خطای `ZeroDivisionError` میشه، پایتون بلافاصله اجرای `try` رو متوقف می‌کنه و به دنبال `except` مناسب می‌گرده.
* `except ZeroDivisionError` دقیقاً همون خطاییه که دنبالشیم، پس کد داخلش اجرا میشه.

گرفتن خطاهای چندگانه

یه وقتایی ممکنه یه بلاک `try`، پتانسیل تولید چند نوع خطای مختلف رو داشته باشه. مثلاً، اگه بخوای یه فایل رو باز کنی، ممکنه فایل پیدا نشه (`FileNotFoundError`) یا اگه فرمت فایل اشتباه باشه، خطای دیگه‌ای رخ بده. پایتون بهت اجازه میده برای هر نوع خطا، یه بلاک `except` جداگانه بنویسی.

مثال: مدیریت فایل و نوع داده

فرض کن یه تابع داریم که سعی می‌کنه یه عدد رو از یه فایل بخونه و تبدیلش کنه به عدد صحیح.

🔗 کپی کد

try:
    file = open("my_data.txt", "r")
    data = file.read()
    number = int(data)
    print(f"عدد خونده شده: {number}")
except FileNotFoundError:
    print("متاسفم، فایل 'my_data.txt' پیدا نشد.")
except ValueError:
    print("اطلاعات داخل فایل رو نمی‌شه به عدد تبدیل کرد، لطفاً فرمت رو برسی کن.")
except Exception as e: # گرفتن هر خطای ناشناس دیگه
    print(f"یه خطای غیرمنتظره پیش اومد: {e}")
finally:
    if 'file' in locals() and not file.closed:
        file.close()
        print("فایل بسته شد.")

خروجی (سناریوهای مختلف):

# اگر فایل my_data.txt وجود نداشته باشد:
متاسفم، فایل 'my_data.txt' پیدا نشد.

# اگر فایل my_data.txt وجود داشته باشد و محتوایش "hello" باشد:
اطلاعات داخل فایل رو نمی‌شه به عدد تبدیل کرد، لطفاً فرمت رو برسی کن.
فایل بسته شد.

# اگر فایل my_data.txt وجود داشته باشد و محتوایش "123" باشد:
عدد خونده شده: 123
فایل بسته شد.

نکات مهم در مورد except های چندگانه:

  • ترتیب اهمیت: پایتون بلاک‌های `except` رو به ترتیب از بالا به پایین بررسی می‌کنه. اگه یه `except` کلی مثل `except Exception` رو قبل از `except` های خاص‌تر بنویسی، اون `except` کلی همه خطاها رو می‌گیره و `except` های بعدی هیچ‌وقت اجرا نمیشن. پس همیشه `except` های خاص رو اول بنویس و `except Exception as e` رو بذار آخر.
  • گرفتن چند خطا با یک بلاک: می‌تونی چند خطا رو با یه `tuple` داخل یه `except` بلاک مدیریت کنی:
    🔗 کپی کد

    try:
        # کدی که ممکنه خطا بده
        value = int("abc")
        # value = 10 / 0
    except (ValueError, ZeroDivisionError) as e:
        print(f"یه خطای تبدیل یا تقسیم بر صفر پیش اومده: {e}")
    

بلاک else: وقتی همه چیز خوب پیش می‌ره

بلاک `else` یه قسمت اختیاریه که می‌تونی بعد از `except` ها اضافه کنی. کدهای داخل `else` فقط زمانی اجرا میشن که هیچ خطایی در بلاک `try` اتفاق نیفتاده باشه. این بلاک برای کارهایی خوبه که فقط در صورت موفقیت‌آمیز بودن `try` باید انجام بشن.

مثال try-except-else

🔗 کپی کد

def safe_divide(a, b):
    try:
        result = a / b
    except ZeroDivisionError:
        print("خطا: نمی‌شه بر صفر تقسیم کرد!")
    except TypeError:
        print("خطا: ورودی‌ها باید عدد باشن.")
    else:
        print(f"نتیجه تقسیم: {result}")
        return result
    finally:
        print("عملیات تقسیم به پایان رسید.")

safe_divide(10, 2)
print("-" * 30)
safe_divide(10, 0)
print("-" * 30)
safe_divide(10, "a")

خروجی:

نتیجه تقسیم: 5.0
عملیات تقسیم به پایان رسید.
------------------------------
خطا: نمی‌شه بر صفر تقسیم کرد!
عملیات تقسیم به پایان رسید.
------------------------------
خطا: ورودی‌ها باید عدد باشن.
عملیات تقسیم به پایان رسید.

می‌بینی؟ `else` فقط وقتی اجرا شد که همه چیز آروم و بی‌خطر بود.

بلاک finally: کارایی که باید همیشه انجام بشن

بلاک `finally` یه بلاک خیلی قدرتمنده که کد داخلش *همیشه* اجرا میشه، فرقی نمی‌کنه که خطایی رخ داده باشه یا نه، یا حتی اگه `return`، `break` یا `continue` هم تو بلاک `try` یا `except` استفاده شده باشه. `finally` برای کارهایی مثل بستن فایل‌ها، آزاد کردن منابع شبکه، یا پاکسازی حافظه عالیه.

مثال: بستن فایل با finally

🔗 کپی کد

file_handle = None
try:
    file_handle = open("non_existent_file.txt", "r") # این فایل وجود نداره
    content = file_handle.read()
    print(content)
except FileNotFoundError:
    print("فایل پیدا نشد.")
finally:
    if file_handle: # مطمئن میشیم که file_handle تعریف شده و None نیست
        file_handle.close()
        print("فایل بسته شد (از داخل finally).")

خروجی:

فایل پیدا نشد.
فایل بسته شد (از داخل finally).

حتی با اینکه خطای `FileNotFoundError` رخ داد، بلاک `finally` اجرا شد و سعی کرد فایل رو ببنده (البته در این مورد `file_handle` هیچوقت مقداردهی نشد، پس باید یه چک برای `None` بودن بذاریم). این یعنی `finally` یه جای امن برای کارهای پاکسازی شماست.

برای آشنایی بیشتر با `snippets` پایتون و استفاده‌های بهینه از کدها، می‌تونی به بخش اسنیپت‌های پایتون در fa-tools.ir سر بزنی.

معرفی و پرتاب استثنائات (raise)

گاهی اوقات، ما خودمون می‌خوایم یه خطا رو “پرتاب” (raise) کنیم. مثلاً، اگه ورودی یه تابع، شرایط خاصی رو نداشته باشه، منطقیه که خودمون یه خطا تولید کنیم تا به بقیه قسمت‌های برنامه بفهمونیم که یه مشکل پیش اومده.

مثال: raise کردن خطا

🔗 کپی کد

def check_age(age):
    if not isinstance(age, (int, float)):
        raise TypeError("سن باید یه عدد باشه.")
    if age < 0:
        raise ValueError("سن نمی‌تونه منفی باشه.")
    if age < 18:
        print("شما هنوز به سن قانونی نرسیده‌اید.")
    else:
        print("شما به سن قانونی رسیده‌اید.")

try:
    check_age(20)
    check_age(-5)
except (TypeError, ValueError) as e:
    print(f"خطا در بررسی سن: {e}")

خروجی:

شما به سن قانونی رسیده‌اید.
خطا در بررسی سن: سن نمی‌تونه منفی باشه.

با `raise`، ما به صورت صریح اعلام می‌کنیم که یه شرایط خطا در برنامه پیش اومده و این خطا باید توسط یه بلاک `except` در سطوح بالاتر مدیریت بشه.

ساخت استثنائات سفارشی (Custom Exceptions)

پایتون کلی خطای داخلی داره، ولی گاهی اوقات لازمه که خطاهای خودت رو تعریف کنی تا مفهوم و منطق برنامه‌ت واضح‌تر باشه. این کار بهت اجازه میده خطاهای معنی‌دارتری رو پرتاب و مدیریت کنی.

چطور یه Exception سفارشی بسازیم؟

خیلی سادست، کافیه یه کلاس جدید بسازی که از کلاس `Exception` یا یکی از فرزندانش (مثل `ValueError`, `TypeError` و …) ارث‌بری کنه.

🔗 کپی کد

class InvalidUserDataError(Exception):
    """خطایی برای اطلاعات نامعتبر کاربر."""
    def __init__(self, message="اطلاعات کاربر نامعتبر است"):
        self.message = message
        super().__init__(self.message)

class UserNotFound(InvalidUserDataError):
    """خطایی که وقتی کاربر پیدا نمی‌شه."""
    def __init__(self, username):
        self.username = username
        super().__init__(f"کاربر '{username}' پیدا نشد.")

def get_user_profile(username):
    if username == "admin":
        return {"username": "admin", "role": "administrator"}
    elif username == "guest":
        return {"username": "guest", "role": "viewer"}
    else:
        raise UserNotFound(username)

try:
    user_data = get_user_profile("ali")
    print(user_data)
except UserNotFound as e:
    print(f"مدیریت خطا: {e}")
except InvalidUserDataError as e: # این بلاک هم می‌تونه خطای UserNotFound رو بگیره
    print(f"خطای کلی‌تر: {e}")

خروجی:

مدیریت خطا: کاربر 'ali' پیدا نشد.

چرا Exception سفارشی؟

  • وضوح کد: خطاهایی با نام‌های معنی‌دار، خوندن و فهمیدن کد رو راحت‌تر می‌کنن.
  • مدیریت دقیق‌تر: می‌تونی خطاهای خاص خودت رو در نقاط مختلف برنامه مدیریت کنی، بدون اینکه با خطاهای داخلی پایتون قاطی بشن.
  • جداسازی مسئولیت‌ها: یه کد می‌تونه خطاهای مربوط به خودش رو raise کنه و یه کد دیگه می‌تونه اونا رو بگیره.

بهترین شیوه‌ها در مدیریت خطا

مدیریت خطا فقط درباره‌ی کد نوشتن نیست، درباره‌ی اینکه چطور فکر کنی و کد رو ساختار بدی هم هست. چند تا نکته‌ی کلیدی رو باهم مرور کنیم:

۱. خطاهای خاص رو بگیر، نه همه چیز رو!

یکی از بزرگترین اشتباهات اینه که با `except Exception as e` تمام خطاها رو بگیری. این کار باعث میشه خطاهای غیرمنتظره و مهم هم پنهان بشن و اشکال‌زدایی رو جهنم کنه. همیشه سعی کن خطاهای مشخص رو بگیری.

🔗 کپی کد

# ❌ بد (Too broad)
try:
    # ... کد
except Exception as e:
    print(f"یه خطایی پیش اومد: {e}")

# ✅ خوب (Specific)
try:
    number = int(input("یه عدد وارد کن: "))
except ValueError:
    print("لطفاً یه عدد صحیح وارد کن!")
except KeyboardInterrupt:
    print("عملیات توسط کاربر متوقف شد.")

۲. پیغام‌های خطا رو کاربرپسند کن

به جای اینکه Traceback پایتون رو به کاربر نشون بدی، یه پیغام واضح و دوستانه بنویس که به کاربر کمک کنه مشکل رو بفهمه و احتمالا حل کنه.

۳. از logging استفاده کن

به جای `print()` در بلاک `except`، از ماژول `logging` پایتون استفاده کن. `logging` بهت اجازه میده خطاها رو در فایل‌ها ذخیره کنی، سطوح مختلفی از خطا (مثل `INFO`, `WARNING`, `ERROR`, `CRITICAL`) داشته باشی و برنامه‌ت رو در محیط‌های تولید (production) بهتر نظارت کنی. این یه موضوع عمیق و مهمه که می‌تونه برای `snippets` و کدهای آماده در آینده به کارت بیاد.

🔗 کپی کد

import logging

logging.basicConfig(level=logging.ERROR, filename='app_errors.log',
                    format='%(asctime)s - %(levelname)s - %(message)s')

try:
    result = 10 / 0
except ZeroDivisionError as e:
    logging.error(f"خطای تقسیم بر صفر: {e}")
    # print("عملیات با شکست مواجه شد. لطفاً بعداً تلاش کنید.")

۴. از with برای منابع استفاده کن

وقتی با فایل‌ها یا منابع شبکه‌ای کار می‌کنی، `with` statement یه راه عالی برای تضمین اینه که منابعت حتی در صورت بروز خطا هم به درستی بسته بشن.

🔗 کپی کد

try:
    with open("my_important_file.txt", "r") as file:
        content = file.read()
        print(content)
except FileNotFoundError:
    print("فایل مهم پیدا نشد!")
# نیازی به file.close() در finally نیست، 'with' خودش هندل می‌کنه.

۵. از بلاک else هوشمندانه استفاده کن

کارهایی که باید فقط در صورت موفقیت `try` انجام بشن رو به بلاک `else` منتقل کن. این کار خوانایی کد رو افزایش میده و مسئولیت‌ها رو جدا می‌کنه.

مقایسه رویکردها: مدیریت خطای عمومی در مقابل خاص

همیشه این سوال پیش میاد که چقدر باید خطاها رو دقیق مدیریت کنیم؟ آیا گرفتن `Exception` کلی همیشه بده؟ بیا تو یه جدول مقایسه کنیم.

ویژگی except SpecificError (رویکرد پیشنهادی)
دقت مدیریت بسیار بالا. می‌تونی برای هر نوع مشکل، راه حل متفاوتی ارائه کنی.
وضوح کد خوانایی بالاتر، چون دقیقاً مشخصه چه خطایی در حال مدیریت شدنه.
اشکال‌زدایی راحت‌تر، چون خطاهای غیرمنتظره همچنان باعث کرش و نمایش Traceback میشن.
پیچیدگی ممکنه نیاز به نوشتن `except` های بیشتری داشته باشی.
موارد استفاده تقریباً در تمام سناریوها، به خصوص در کدهای تولیدی و برنامه‌های بزرگ.
ویژگی except Exception (رویکرد عمومی)
دقت مدیریت پایین. همه خطاها رو یکسان مدیریت می‌کنه.
وضوح کد کاهش خوانایی، چون مشخص نیست چه خطاهای خاصی رو کنترل می‌کنی.
اشکال‌زدایی بسیار دشوار، چون خطاهای مهم پنهان می‌شن و برنامه کرش نمی‌کنه.
پیچیدگی کمتر، نیاز به نوشتن بلاک‌های `except` کمتری داره.
موارد استفاده در بالاترین سطح برنامه (برای گرفتن خطاهای نهایی)، یا در کدهای کوچک و سریع که پیچیدگی اهمیت نداره.

عیب‌یابی سریع (Troubleshooting)

بعضی وقت‌ها با وجود استفاده از `try-except` باز هم ممکنه به مشکلاتی بربخوری. بیا چند تا سناریوی رایج رو ببینیم و راه حلشون رو پیدا کنیم:

مشکل ۱: چرا finally من اجرا نمی‌شه؟

  • سناریو: برنامه‌ات با `sys.exit()` یا `os._exit()` بسته میشه.
  • راه حل: بلاک `finally` در پایتون تضمین می‌کنه که کدهای داخلش اجرا بشن، *مگر اینکه* برنامه به صورت غیرعادی و ناگهانی خاتمه پیدا کنه (مثلاً با `os._exit()` یا کشته شدن پروسه). برای خروج عادی از برنامه از `sys.exit()` استفاده کن که `finally` رو اجرا می‌کنه، اما اگه مجبور به استفاده از `os._exit()` هستی (که خیلی کم پیش میاد)، باید بدونی که `finally` رو دور می‌زنه.

مشکل ۲: یه خطا توی بلاک except یا finally رخ داده!

  • سناریو: حین مدیریت خطا (توی `except`) یا پاکسازی منابع (توی `finally`)، یه خطای جدید پیش میاد.
  • راه حل:
    • برای except: اگه کدت توی `except` خودش خطا میده، یعنی داری کار پیچیده‌ای انجام میدی. سعی کن کد `except` رو ساده نگه داری. اگه لازمه، می‌تونی یه `try-except` دیگه تو دل `except` اصلی بذاری (هرچند معمولاً نشونه‌ی یه کد با ساختار غیر بهینه است).
    • برای finally: کدی که تو `finally` می‌نویسی باید فوق‌العاده قابل اطمینان باشه و خودش خطا تولید نکنه. مثلاً قبل از بستن یه فایل، چک کن که `handle` فایل `None` نباشه (مثل مثالی که بالاتر زدیم).

مشکل ۳: چرا متغیری که تو try تعریف کردم، تو except در دسترس نیست؟

  • سناریو: یه متغیر رو فقط تو بلاک `try` تعریف کردی و بعد از یه خطا، تو `except` بهش دسترسی نداری.
  • راه حل: متغیر رو قبل از بلاک `try` با یه مقدار پیش‌فرض (مثل `None`) مقداردهی اولیه کن. اینجوری حتی اگه `try` با خطا مواجه بشه و متغیر داخلش تعریف نشه، تو `except` یا `finally` می‌تونی بهش دسترسی داشته باشی و وضعیتش رو بررسی کنی.
🔗 کپی کد

data = None # مقداردهی اولیه
try:
    file = open("non_existent_file.txt", "r")
    data = file.read()
except FileNotFoundError:
    print("فایل پیدا نشد.")
    if data is None:
        print("متغیر 'data' هنوز None است.")

نتیجه‌گیری

مدیریت خطا با `try except` یکی از ستون‌های اصلی نوشتن کدهای پایتون قوی و قابل اعتماد هست. با استفاده درست از `try`, `except`, `else`, `finally` و تعریف استثنائات سفارشی، می‌تونی برنامه‌هایی بنویسی که نه تنها عملکرد بهتری دارن، بلکه در مواجهه با مشکلات هم هوشمندانه رفتار می‌کنن و تجربه کاربری بهتری رو ارائه میدن. فراموش نکن که هدف، پیش‌بینی مشکلات و آماده بودن برای مقابله با اوناست، نه صرفاً پنهان کردنشون.

🛠️ ابزارهای بیشتر برای برنامه‌نویس‌ها

اگه دنبال اسنیپت‌های CSS، JS، HTML یا حتی کدهای آماده وردپرس هستی، حتماً یه سر به بخش اسنیپت‌های ما بزن. یه دنیا کد آماده و کاربردی اونجا منتظرته که کلی در وقتت صرفه‌جویی می‌کنه و بهت کمک می‌کنه تا پروژه‌هات رو سریع‌تر و با کیفیت‌تر پیش ببری.

پرسش‌های متداول (FAQ)

۱. چه تفاوتی بین try-except و if-else برای مدیریت شرایط خطا وجود دارد؟

try-except برای مدیریت “استثنائات” (Exceptions) یا خطاهای غیرمنتظره‌ای که اجرای عادی برنامه را مختل می‌کنند استفاده می‌شود، در حالی که if-else برای مدیریت “شرایط” (Conditions) مورد انتظار و منطق‌های طبیعی برنامه به کار می‌رود. مثلاً، چک کردن اینکه آیا یک فایل وجود دارد یا نه با if-else ممکن است، اما اگر فایل به طور غیرمنتظره‌ای حذف شود، try-except برای FileNotFoundError مناسب‌تر است.

۲. آیا استفاده از except Exception as e همیشه اشتباه است؟

خیر، همیشه اشتباه نیست اما باید با احتیاط استفاده شود. این رویکرد می‌تواند خطاهای مهم و پیش‌بینی نشده را پنهان کند. بهترین حالت این است که از except Exception as e در بالاترین سطح برنامه (مثلاً در یک تابع اصلی که تمام عملیات را دربرمی‌گیرد) استفاده کنید تا جلوی کرش کردن ناگهانی کل برنامه را بگیرد، اما در سطوح پایین‌تر کد، خطاهای خاص را مدیریت کنید.

۳. چه زمانی باید از finally استفاده کنیم؟

بلاک finally زمانی استفاده می‌شود که نیاز دارید کدی را بدون توجه به اینکه خطایی رخ داده یا نه، همیشه اجرا کنید. رایج‌ترین کاربرد آن برای پاکسازی منابع است، مانند بستن فایل‌ها، اتصال به دیتابیس یا آزاد کردن قفل‌ها. این تضمین می‌کند که منابع سیستم به درستی مدیریت شوند.

۴. چطور می‌توانیم استثنائات سفارشی (Custom Exceptions) بسازیم؟

برای ساخت یک استثنای سفارشی، کافی است یک کلاس جدید تعریف کنید که از کلاس Exception یا یکی از زیرکلاس‌های آن (مانند ValueError یا TypeError) ارث‌بری کند. این کار به شما امکان می‌دهد خطاهایی با نام‌های معنی‌دارتر ایجاد کرده و آن‌ها را به صورت اختصاصی مدیریت کنید.

function copyCode(element) {
const codeBlock = element.nextElementSibling.querySelector(‘pre’);
const textToCopy = codeBlock.textContent;
navigator.clipboard.writeText(textToCopy).then(() => {
const originalText = element.textContent;
element.textContent = ‘✅ کپی شد!’;
setTimeout(() => {
element.textContent = originalText;
}, 2000);
}).catch(err => {
console.error(‘Failed to copy text: ‘, err);
});
}

Table of Contents

آخرین نوشته‌ها