ویژگی تصویر

آشنایی با کتابخانه traceback در پایتون

  /  پایتون   /  کتابخانه traceback در پایتون
بنر تبلیغاتی الف

کتابخانه traceback در پایتون ابزاری استاندارد و قدرتمند برای کار با استک‌ترِیس‌ها (stack traces) و نمایش جزئیات استثناهاست. این ماژول برای دیباگ، لاگینگ و نمایش ارورها در محیط‌های تولید یا توسعه کاربرد زیادی دارد. در این مقاله مفاهیم پایه، توابع کلیدی، مثال‌های کاربردی و نکات پیشرفته مرتبط با traceback را به صورت واضح و عملی توضیح می‌دهم.

چرا traceback مهم است؟

هنگامی که برنامه شما با خطا مواجه می‌شود، استک‌ترِیس نشان می‌دهد که چه توابعی به ترتیب فراخوانی شده‌اند تا به نقطه خطا برسند. اطلاعاتی مانند نام فایل، شماره خط و متن کد بسیار مفیدند. ماژول traceback این اطلاعات را به فرمت‌های مناسب برای چاپ، ذخیره یا پردازش بازمی‌گرداند.

وارد کردن و استفاده ساده

برای شروع کافیست ماژول را وارد کنید:

import traceback

در ادامه مثال‌هایی از کاربردهای رایج را می‌بینید.

print_exc و format_exc — نمایش سریع استک‌ترِیس

import traceback

try:
    1 / 0
except Exception:
    traceback.print_exc()
    # متن استک‌ترِیس را به صورت رشته دریافت کنیم:
    err_str = traceback.format_exc()
    print("Captured:", err_str)

در این مثال، تابع print_exc() مستقیماً استک‌ترِیس را به stdout چاپ می‌کند. تابع format_exc() همان متن را به عنوان رشته برمی‌گرداند که برای لاگ کردن یا ارسال در پاسخ‌های HTTP مفید است.

format_exception و format_exception_only

import traceback, sys

try:
    int("not_a_number")
except Exception as e:
    tb = sys.exc_info()[2]
    lines = traceback.format_exception(type(e), e, tb)
    print("".join(lines))

تابع format_exception لیستی از رشته‌ها برمی‌گرداند که ترکیب‌شان معادل استک‌ترِیس کامل است. اگر تنها پیام خطا (بدون استک) را بخواهید، از format_exception_only استفاده کنید.

استخراج فریم‌ها: extract_tb و extract_stack

import traceback

def a():
    b()

def b():
    c()

def c():
    try:
        raise ValueError("bad value")
    except:
        tb_list = traceback.extract_tb(__import__('sys').exc_info()[2])
        for frame in tb_list:
            print(frame.filename, frame.lineno, frame.name)
            
a()

extract_tb لیستی از اشیاء FrameSummary بازمی‌گرداند که اطلاعات ساختاری مثل نام فایل، شماره خط و نام تابع را دارند—مناسب برای پردازش برنامه‌محور یا نمایش سفارشی.

TracebackException — API مدرن و ساختارمند

import traceback

try:
    raise KeyError("missing")
except Exception as e:
    tb_exc = traceback.TracebackException.from_exception(e)
    print("".join(tb_exc.format()))

کلاس TracebackException طراحی شده تا اطلاعات خطا را با امکان دسترسی به زنجیره‌های استثنا (chained exceptions) و فرمت‌بندی پیشرفته مدیریت کند. این API خواناتر و انعطاف‌پذیرتر از توابع قدیمی‌تر است.

ادغام با logging

import logging

logging.basicConfig(level=logging.ERROR)

try:
    1 / 0
except Exception:
    logging.exception("Division failed")

تابع logging.exception به‌صورت خودکار استک‌ترِیس فعلی را به لاگ اضافه می‌کند (با سطح ERROR). این روش معمول و امن برای لاگ کردن خطاها در برنامه‌های واقعی است.

مدیریت استثنای زنجیره‌ای (Exception Chaining)

پایتون از قابلیت chaining پشتیبانی می‌کند (raise … from …). traceback می‌تواند این زنجیره‌ها را نشان دهد که در تحلیل علت ریشه‌ای خطا بسیار ارزشمند است.

import traceback

def inner():
    raise ValueError("inner error")

def outer():
    try:
        inner()
    except Exception as e:
        raise RuntimeError("outer error") from e

try:
    outer()
except Exception as e:
    print("".join(traceback.TracebackException.from_exception(e).format()))

در این نمونه، خروجی شامل هر دو استثنای داخلی و خارجی است تا بفهمیم چه چیزی باعث وقوع خطای نهایی شده است.

ذخیره استک‌ترِیس در فایل و ارسال به سرویس‌ها

import traceback

try:
    1 / 0
except Exception:
    with open("error.log", "a") as f:
        traceback.print_exc(file=f)

می‌توانید از print_exc یا format_exc برای ذخیره در فایل یا ارسال به سیستم‌های مانیتورینگ استفاده کنید. در سرویس‌های تولید، اغلب ترجیح می‌دهیم اطلاعات حساسی را پیش از ذخیره فیلتر کنیم.

جدول توابع مهم

تابع / کلاسکاربرد
print_exc()چاپ فوری استک‌ترِیس
format_exc()دریافت استک‌ترِیس به‌صورت رشته
format_exception()فرمت کامل استثنا با تیپ و traceback
extract_tb()استخراج فریم‌ها برای پردازش
TracebackExceptionAPI ساخت‌یافته برای پردازش و فرمت

نکات حرفه‌ای و بهترین شیوه‌ها

  • برای لاگینگ از logging.exception استفاده کنید تا فرمت‌ها و سطوح لاگ یکپارچه بماند.
  • در محیط‌های تولید اطلاعات حساس (مثل مسیرهای محلی یا محتوای متغیرها) را قبل از ارسال به لاگ یا سرویس‌های خارجی ماسک کنید.
  • برای سیستم‌های async و coroutine، از TracebackException یا لاگینگ سازگار با asyncio استفاده کنید چون ساختار استک متفاوت است.
  • پردازش خودکار استک‌ترِیس (مثل ارسال به Sentry یا ذخیره در دیتابیس) بسیار کمک‌کننده است؛ اما حجم و حجم تکراری را کنترل کنید.

خطاها و موارد قابل توجه

گاهی استک‌های بسیار بزرگ یا چرخه‌ای دیده می‌شود؛ در اغلب مواقع محدود کردن عمق چاپ یا استفاده از limit در توابع extract/format مفید است. همچنین به خاطر داشته باشید که گرفتن traceback پس از پاک شدن استثنا (مثلاً ذخیره در فایل بعد از مدت طولانی) ممکن است اطلاعات محیطی را از دست بدهد.

جمع‌بندی

ماژول traceback یکی از ابزارهای کلیدی برای خطایابی و ثبت استک‌ترِیس در پایتون است. با ترکیب توابع سنتی (مثل print_exc) و API مدرن (TracebackException) می‌توانید استراتژی‌های مختلفی برای لاگینگ، تحلیل و ارسال خطاها پیاده کنید. رعایت نکات امنیتی و مدیریت حجم لاگ‌ها هنگام به‌کارگیری در محیط تولید اهمیت بالایی دارد.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: