کتابخانه‌ی استاندارد · سیستم و ابزار

خطا os/error

آخرین خطای عملیات پرونده و فرآیند: کد، پیام و مسیری که مشکل داشته.

واردسازی سیستم عامل.خطا

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

تابع‌های ساده‌ی بسته‌ی سیستم عامل چیزی این‌جا ثبت نمی‌کنند و فقط -۱ برمی‌گردانند. این بسته با بسته‌ی عمومی خطا فرق دارد که مقدار خطا برای برگرداندن از تابع‌های خودتان می‌سازد؛ برای کد تازه‌ای که به پرونده و فرآیند مربوط نیست، آن را ترجیح دهید.

پیش از تصمیم‌گیری بر پایه‌ی کد، بدانید بسته‌های استاندارد واقعاً چه چیزی ثبت می‌کنند:

کدثبت‌کننده
خطای ورودی خروجیتقریباً همه‌ی شکست‌ها: پوشه (ساختن، حذف، رونوشت و جابه‌جایی)، پرونده (نوشتن اتمی، رونوشت و جابه‌جایی) و موقت
پرونده یافت نشدفقط پرونده.حذف، برای هر شکستی در حذف، کمبود مجوز هم
فرآیند ناموفقفرآیند، وقتی برنامه‌ای اجرا نمی‌شود
بقیههنوز هیچ بخشی از کتابخانه‌ی استاندارد؛ برای تنظیم خطای خودتان‌اند

خواندن‌ها و نوشتن‌های ساده، مثل پرونده.خواندن متن و نوشتن متن، چیزی ثبت نمی‌کنند؛ نتیجه‌شان را بررسی کنید. پیام‌ها عبارت‌های ثابت انگلیسی مثل delete failed هستند، نه دلیلی که سیستم گفته، و system_code را فقط فرآیند پر می‌کند.

بررسی یک عملیات و توضیح شکست آن

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

os-error-guide-explain.salam
واردسازی سیستم عامل.خطا
واردسازی سیستم پرونده.پرونده

تابع توضیح(خ: خطا.خطای سیستم عامل): رشته:
    ترابرد خ.کد:
        خطا.پرونده یافت نشد: برگشت "چنین پرونده‌ای نیست: " + خ.مسیر پایان
        خطا.خطای ورودی خروجی: برگشت خ.عملیات + " روی " + خ.مسیر + " شکست خورد" پایان
        خطا.فرآیند ناموفق: برگشت "این برنامه اجرا نشد: " + خ.مسیر پایان
    پایان
    برگشت "مشکل دیگری پیش آمد در " + خ.عملیات
پایان

تابع حذف پیش نویس(نام: رشته):
    خطا.پاک کردن خطا()
    پرونده.حذف(نام)
    اگر خطا.خطا دارد():
        سرچاپ "حذف نشد:"، توضیح(خطا.آخرین خطا())
        برگشت
    پایان
    سرچاپ "حذف شد:"، نام
پایان

تابع ریشه:
    پرونده.نوشتن متن("پیش‌نویس.txt"، "یادداشت")
    حذف پیش نویس("پیش‌نویس.txt")
    حذف پیش نویس("پیش‌نویس.txt")
پایان
خروجیحذف شد: پیش‌نویس.txt حذف نشد: چنین پرونده‌ای نیست: پیش‌نویس.txt

برای تصمیم‌گیری code را با ثابت‌های این بسته مقایسه کنید، نه message را: پیام برای خواندن آدم‌هاست و ممکن است از نسخه‌ای به نسخه‌ی دیگر عوض شود.

خطا تا پاکش نکنید می‌ماند

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

os-error-guide-clear.salam
واردسازی سیستم عامل.خطا
واردسازی سیستم پرونده.پرونده

تابع ریشه:
    پرونده.حذف("گمشده.txt")
    پرونده.نوشتن متن("سالم.txt"، "خوب")
    سرچاپ "پس از یک نوشتن موفق:"، خطا.خطا دارد()، خطا.پیام آخرین خطا()
    خطا.پاک کردن خطا()
    پرونده.نوشتن متن("سالم.txt"، "هنوز خوب")
    سرچاپ "پس از پاک کردن و یک نوشتن موفق:"، خطا.خطا دارد()
    پرونده.حذف("سالم.txt")
    سرچاپ "پس از حذف سالم.txt:"، خطا.خطا دارد()
پایان
خروجیپس از یک نوشتن موفق: true delete failed پس از پاک کردن و یک نوشتن موفق: false پس از حذف سالم.txt: false

این ثبت فقط یک مقدار سراسری برای کل برنامه است، پس راه مطمئنی برای رساندن خطا میان نخ‌ها نیست: شکست در یک نخ می‌تواند خطای نخ دیگر را پیش از خوانده شدن رونویسی کند. خطا را در همان نخ و بلافاصله پس از فراخوانی بررسی کنید.

گزارش خطا از تابع‌های خودتان

تنظیم خطا خطایی را به همان شیوه‌ی بسته‌های استاندارد ثبت می‌کند. تابع کمکی‌ای که پرونده می‌خواند می‌تواند از آن استفاده کند و فراخواننده‌ها آن را با همان خطا دارد و آخرین خطا بررسی می‌کنند که همه‌جا به کار می‌برند. نام تابعتان را به‌عنوان عملیات و پرونده را به‌عنوان مسیر بدهید تا پیام نشان دهد کار کجا خراب شد.

os-error-guide-own.salam
واردسازی سیستم عامل.خطا
واردسازی سیستم پرونده.پرونده

تابع خواندن درگاه(مسیر: رشته): صحیح:
    خطا.پاک کردن خطا()
    اگر وارونه پرونده.وجود دارد(مسیر):
        خطا.تنظیم خطا(خطا.پرونده یافت نشد، "پرونده‌ی تنظیمات نیست"، "خواندن درگاه"، مسیر، ۰)
        برگشت ۰
    پایان
    متن := پرونده.خواندن متن(مسیر).پیراست()
    درگاه := متن.به صحیح()
    اگر درگاه <= ۰ یا درگاه > ۶۵۵۳۵:
        خطا.تنظیم خطا(خطا.مسیر نامعتبر، "شماره‌ی درگاه نیست: " + متن، "خواندن درگاه"، مسیر، ۰)
        برگشت ۰
    پایان
    برگشت درگاه
پایان

تابع نمایش(مسیر: رشته):
    درگاه := خواندن درگاه(مسیر)
    اگر خطا.خطا دارد():
        خ := خطا.آخرین خطا()
        سرچاپ خ.عملیات + "(" + خ.مسیر + "):"، خ.پیام
        برگشت
    پایان
    سرچاپ مسیر، "می‌گوید درگاه"، درگاه
پایان

تابع ریشه:
    پرونده.نوشتن متن("درست.conf"، "8080\n")
    پرونده.نوشتن متن("خراب.conf"، "هشتاد\n")
    نمایش("درست.conf")
    نمایش("خراب.conf")
    نمایش("ناموجود.conf")
    پرونده.حذف("درست.conf")
    پرونده.حذف("خراب.conf")
پایان
خروجیدرست.conf می‌گوید درگاه 8080 خواندن درگاه(خراب.conf): شماره‌ی درگاه نیست: هشتاد خواندن درگاه(ناموجود.conf): پرونده‌ی تنظیمات نیست

برنامه‌ای که اجرا نمی‌شود

بسته‌ی فرآیند وقتی اصلاً نتواند برنامه‌ای را اجرا کند، مثلاً چون مسیرش غلط است، اینجا فرآیند ناموفق را ثبت می‌کند. این با برنامه‌ای که اجرا می‌شود و با کدی غیر صفر بیرون می‌آید فرق دارد: در آن حالت اینجا خطایی نیست و کد را از انتظار می‌خوانید.

os-error-guide-process.salam
واردسازی سیستم عامل.خطا
واردسازی سیستم عامل.فرآیند

تابع ریشه:
    ناپایا آرگ := وکتور {} برگردان وکتور<رشته>
    دیرکن آرگ.آزادکن()
    آرگ.بیفزا("--version")
    خطا.پاک کردن خطا()
    ناپایا ف := فرآیند.شروع با ضبط("/no/such/program"، آرگ)
    اگر خطا.خطا دارد():
        خ := خطا.آخرین خطا()
        سرچاپ "اجرا نشد:"، خ.کد == خطا.فرآیند ناموفق، خ.عملیات، خ.مسیر
        برگشت ۰
    پایان
    کد := فرآیند.انتظار(ف)
    فرآیند.پاکسازی(ف)
    سرچاپ "اجرا شد، ولی با این کد بیرون آمد:"، کد
پایان
خروجیاجرا نشد: true StartCaptured /no/such/program

فیلد system_code شماره‌ی خود سیستم عامل را نگه می‌دارد، اگر بسته آن را بداند: نتیجه‌ی posix_spawnp در یونیکس و GetLastError در ویندوز، آن هم فقط از فرآیند. در بقیه‌ی جاها صفر است. برای گزارش‌ها به کار می‌آید؛ تصمیم را بر پایه‌ی code بگیرید.

گونه‌ها

خطای سیستم عامل OSError

ساختار خطای سیستم عامل
جزئیات یک خطا.
نامانگلیسیگونهتوضیح
کدcodeصحیح = 0کد خطا؛ یکی از ثابت‌های بالا.
پیامmessageرشته = ""عبارت ثابت و کوتاه انگلیسی مثل mkdir failed؛ دلیلی را که سیستم گفته در خود ندارد.
عملیاتoperationرشته = ""نام تابعی که خطا داده.
مسیرpathرشته = ""مسیری که مشکل داشته.
کد سیستمsystem_codeصحیح = 0شماره‌ی خطای خود سیستم عامل اگر معلوم باشد؛ فقط فرآیند پرش می‌کند و در بقیه‌ی جاها ۰ است.
os-error-Last.salam
واردسازی سیستم عامل.خطا
واردسازی سیستم پرونده.پرونده

تابع ریشه:
    خطا.پاک کردن خطا()
    سرچاپ خطا.خطا دارد()
    پرونده.حذف("پرونده‌ای که وجود ندارد.txt")
    اگر خطا.خطا دارد():
        خ := خطا.آخرین خطا()
        سرچاپ خ.کد == خطا.پرونده یافت نشد، خ.عملیات، خ.پیام
        سرچاپ خطا.کد آخرین خطا()، خطا.پیام آخرین خطا()
    پایان
    خطا.تنظیم خطا(خطا.پایان زمان، "زمان تمام شد"، "انتظار"، ""، ۰)
    سرچاپ خطا.کد آخرین خطا() == خطا.پایان زمان، خطا.پیام آخرین خطا()
    سرچاپ خطا.بدون خطا، خطا.دسترسی رد شد، خطا.از قبل موجود است، خطا.مسیر نامعتبر، خطا.پشتیبانی نمی شود، خطا.خطای ورودی خروجی، خطا.فرآیند ناموفق
پایان
خروجیfalse true Delete delete failed 1 delete failed true زمان تمام شد 0 2 3 4 5 6 8

پایاها و متغیرها

بدون خطا None

پایا بدون خطا: صحیح۳۲ = 0
بدون خطا.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

پرونده یافت نشد FileNotFound

پایا پرونده یافت نشد: صحیح۳۲ = 1
پرونده یا پوشه پیدا نشد. در کتابخانه‌ی استاندارد فقط پرونده.حذف آن را ثبت می‌کند، برای هر حذف ناموفق.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

دسترسی رد شد PermissionDenied

پایا دسترسی رد شد: صحیح۳۲ = 2
اجازه‌ی دسترسی نیست. هنوز هیچ بسته‌ی استانداردی آن را ثبت نمی‌کند؛ کار ممنوع به شکل خطای ورودی خروجی دیده می‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

از قبل موجود است AlreadyExists

پایا از قبل موجود است: صحیح۳۲ = 3
از قبل وجود دارد. بسته‌های استاندارد ثبتش نمی‌کنند؛ برای تنظیم خطای خودتان است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

مسیر نامعتبر InvalidPath

پایا مسیر نامعتبر: صحیح۳۲ = 4
مسیر نادرست است. بسته‌های استاندارد ثبتش نمی‌کنند؛ برای تنظیم خطای خودتان است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

پشتیبانی نمی شود NotSupported

پایا پشتیبانی نمی شود: صحیح۳۲ = 5
این کار روی این سیستم پشتیبانی نمی‌شود. بسته‌های استاندارد ثبتش نمی‌کنند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

خطای ورودی خروجی IOError

پایا خطای ورودی خروجی: صحیح۳۲ = 6
خطای خواندن، نوشتن یا سیستم پرونده: کدی که بیشتر شکست‌ها در پوشه، پرونده و موقت ثبت می‌کنند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

پایان زمان Timeout

پایا پایان زمان: صحیح۳۲ = 7
زمان به پایان رسید. بسته‌های استاندارد ثبتش نمی‌کنند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

فرآیند ناموفق ProcessFailed

پایا فرآیند ناموفق: صحیح۳۲ = 8
اجرای فرآیند شکست خورد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

تابع‌ها

تنظیم خطا Set

تابع تنظیم خطا(code: صحیح، message: رشته، operation: رشته، path: رشته، system_code: صحیح)
یک خطا ثبت می‌کند و جای خطای قبلی را می‌گیرد؛ برای وقتی که خودتان بسته‌ای می‌نویسید و می‌خواهید با همین سازوکار گزارش خطا بدهید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

پاک کردن خطا Clear

تابع پاک کردن خطا()
خطای ثبت‌شده را پاک می‌کند؛ پیش از عملیاتی که می‌خواهید خطایش را جدا بررسی کنید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

آخرین خطا Last

تابع آخرین خطا(): خطای سیستم عامل
آخرین خطای ثبت‌شده با همه‌ی جزئیات؛ فراخوانی موفق آن را پاک نمی‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

کد آخرین خطا LastCode

تابع کد آخرین خطا(): صحیح
کد آخرین خطا.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

پیام آخرین خطا LastMessage

تابع پیام آخرین خطا(): رشته
پیام آخرین خطا.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam

خطا دارد HasError

تابع خطا دارد(): منطقی
اگر از آخرین پاک کردن خطا تاکنون خطایی ثبت شده باشد، درست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-error-Last.salam