מה זה טיפול בחריגות (Exception Handling)?
טיפול בחריגות (exception handling) הוא דרך של תוכנית להגיב לשגיאות שקורות בזמן שהיא רצה. קוד שעלול להיכשל נכנס לבלוק מוגן, כמו try, וכשנזרקת שגיאה, השליטה קופצת למטפל, כמו except או catch, במקום שהתוכנית תקרוס.
עודכן ב-24 בספטמבר 2026
תוכנית ששואלת אנשים בני כמה הם תקבל במוקדם או במאוחר "twenty" במקום 20. המרת הטקסט הזה היא שגיאת זמן ריצה: int("twenty") זורק ValueError, ובלי תוכנית פעולה לזה התוכנית נעצרת. טיפול בחריגות הוא תוכנית הפעולה הזו. מסמנים את הקוד שעלול להיכשל, וכותבים את הקוד שירוץ אם הוא אכן נכשל.
Next year you will be 35
Not a number: twenty
Next year you will be 20
Done
התשובה הלא תקינה מדווחת, והלולאה ממשיכה לתשובה הבאה. בלי ה-try, התוכנית הייתה מדפיסה שורה אחת ואז traceback.
איך טיפול בחריגות עובד
- הקוד שבתוך
tryרץ כרגיל. - פעולה נכשלת, וסביבת הריצה זורקת חריגה: אובייקט עם סוג (
ValueError) והודעה (invalid literal for int() with base 10: 'twenty'). - בלוק ה-
tryנעצר בשורה הזו. שאר השורות שלו מדולגות, ולכן "Next year you will be" לא מודפס עבור "twenty". - סביבת הריצה משווה את סוג החריגה לכל פסקת
except, מלמעלה למטה, ומריצה את הראשונה שמתאימה. - אחרי שהמטפל מסיים, התוכנית ממשיכה מהשורה הראשונה שאחרי כל פקודת ה-
try. - אם אף פסקה לא מתאימה, החריגה יוצאת מהפונקציה הנוכחית והחיפוש ממשיך בפונקציה שקראה לה, ואז בזו שקראה לה. לזה קוראים פריסת מחסנית הקריאות (unwinding). אם החיפוש מגיע לראש התוכנית בלי התאמה, התוכנית מסתיימת עם traceback.
שלב 6 אומר שהמטפל לא חייב להיות בפונקציה שבה השגיאה קורית. כאן הכשל נמצא שתי קריאות לעומק, והמטפל שלמטה עדיין תופס אותו:
parsing 4.50
parsing free
Could not add the prices: could not convert string to float: 'free'
float("free") נכשל בתוך parse_price. לא ל-parse_price ולא ל-total היה מטפל, ולכן שתיהן ננטשו, ו-"3.20" אף פעם לא נותח. זו בחירת התכנון העיקרית שטיפול בחריגות נותן לכם: לטפל בשגיאה במקום שבו יודעים מה לעשות איתה, ולרוב זה רחוק מהמקום שבו היא קרתה.
try, except, else ו-finally
לפקודת try של Python יש עוד שני חלקים אופציונליים. else רץ רק כשבלוק ה-try הסתיים בלי חריגה. finally רץ בכל מקרה: אחרי הצלחה, אחרי חריגה שטופלה, ואפילו כשהפונקציה חוזרת מתוך ה-try.
no error
finally runs either way
2.0
b was zero
finally runs either way
None
finally הוא המקום לניקוי: סגירת קובץ, שחרור נעילה, סגירת חיבור למסד נתונים. ב-Python, פקודת with עושה את הניקוי הזה לקבצים אוטומטית, והיא הבחירה הרגילה עבורם.
זריקת חריגות משלכם
חריגות לא נועדו רק לשגיאות שהשפה מזהה. כשפונקציה שלכם מקבלת קלט שהיא לא יכולה לעבוד איתו, היא יכולה לזרוק חריגה כדי לסרב, ומי שקרא לה מחליט מה קורה הלאה. הגדרה של מחלקת חריגה קטנה נותנת לשגיאה שם שמתאר אותה.
70
Refused: cannot take 250, balance is 100
Python משתמשת ב-raise. Java, C++ ו-JavaScript משתמשות ב-throw לאותה מטרה.
טיפול בחריגות בשפות אחרות
| שפה | מילות מפתח | כדאי לדעת |
|---|---|---|
| Python | try, except, else, finally, raise | כל חריגה היא אובייקט שיורש מ-BaseException |
| Java | try, catch, finally, throw, throws | חריגות מסוג checked כמו IOException חייבות להיתפס או להיות מוצהרות עם throws |
| C++ | try, catch, throw | אין finally; דסטרקטורים מנקים בזמן פריסת המחסנית |
| JavaScript | try, catch, finally, throw | שגיאות בקוד async נתפסות עם try סביב await |
| C | אין | פונקציות מחזירות קוד שגיאה, ורבות מהן קובעות את errno |
| Go | אין לשגיאות רגילות | פונקציות מחזירות ערך error שהקורא בודק |
אותה דוגמת ניתוח ב-Java נראית כך:
try {
int age = Integer.parseInt("twenty");
System.out.println(age + 1);
} catch (NumberFormatException e) {
System.out.println("Not a number: " + e.getMessage());
} finally {
System.out.println("done");
}
Java מחלקת חריגות לשתי קבוצות. חריגות מסוג checked, כמו IOException, מתארות בעיות שמחוץ לשליטת התוכנית, והקומפיילר מסרב לבנות קוד שלא תופס אותן וגם לא מצהיר עליהן. חריגות מסוג unchecked, תת מחלקות של RuntimeException כמו NullPointerException, מעידות בדרך כלל על באג, והקומפיילר לא מחייב לטפל בהן.
טעויות נפוצות
- לתפוס הכול.
except:ריק ב-Python תופס גם אתKeyboardInterrupt, כך ש-Ctrl+C מפסיק לעבוד, ו-except Exception:תופס באגים שמעולם לא תכננתם. תפסו את הסוג הספציפי שאתם יודעים לטפל בו. - לבלוע את השגיאה.
except ValueError: passמסתיר את הבעיה. לכל הפחות, הדפיסו או רשמו ביומן מה השתבש. - בלוק
tryגדול מדי. עטפו רק את השורות שיכולות לזרוק את החריגה שאתם תופסים, כדי ששגיאה לא קשורה לא תטופל בטעות. - לתפוס באגים במקום לתקן אותם.
IndexErrorמלולאה שרצה צעד אחד יותר מדי הוא טעות בקוד. טיפול בו משאיר את הקוד השגוי בחיים. - לצפות ש-
catchיעצור קריסה ב-C או ב-C++. Segmentation fault הוא אות (signal) ממערכת ההפעלה, לא חריגה, וב-Linux וב-macOScatch (...)של C++ אף פעם לא רואה אותו.
לאן ממשיכים מכאן
השגיאות שטיפול בחריגות מגיב אליהן מתוארות בעמוד על שגיאת זמן ריצה, והקריסה שהוא לא יכול לתפוס בעמוד על segmentation fault. לתחביר המלא, קראו את המדריכים לחריגות ב-Python, לtry ו-catch ב-Java, לחריגות ב-C++ ולtry ו-catch ב-JavaScript. קורס Java וקורס Python מתרגלים את הנושא בתרגילים אמיתיים.
שאלות נפוצות
מהן 5 מילות המפתח לטיפול בחריגות ב-Java?
try, catch, finally, throw ו-throws. try מסמן את הקוד שצריך לעקוב אחריו, catch מטפל בסוג מסוים של חריגה, ו-finally מריץ קוד ניקוי בין אם הייתה חריגה ובין אם לא. throw זורק חריגה, ו-throws בחתימה של מתודה מצהיר אילו חריגות מסוג checked המתודה יכולה להעביר למי שקרא לה.מה זה טיפול בחריגות ב-C++?
try, catch ו-throw. אפשר לזרוק כל טיפוס, אבל לפי המוסכמה זורקים אובייקט שיורש מ-std::exception, כמו std::runtime_error, ותופסים אותו לפי הפניה: catch (const std::exception& e). ב-C++ אין finally; הניקוי קורה בדסטרקטורים, שרצים אוטומטית בזמן פריסת המחסנית.מה ההבדל בין שגיאה לחריגה?
Exception מכסה בעיות שתוכנית יכולה לטפל בהן באופן סביר, ואילו Error, כמו OutOfMemoryError או StackOverflowError, מסמן כשל של ה-JVM שבדרך כלל תוכנית לא צריכה לנסות לתפוס. ב-Python, ValueError ו-ZeroDivisionError הן שתיהן חריגות, למרות השמות שלהן.מה ההבדל בין throw ל-throws ב-Java?
throw היא פקודה שזורקת חריגה אחת באותה נקודה: throw new IllegalArgumentException("negative age");. throws הוא חלק מהצהרה של מתודה שמפרט את החריגות מסוג checked שהמתודה עשויה להעביר למי שקרא לה: void load() throws IOException. אז הקומפיילר מחייב כל קורא לתפוס את החריגה הזו או להצהיר עליה גם הוא.האם טיפול בחריגות מאט את הקוד?
try זולה ברוב השפות המודרניות. מאז Python 3.11, try כמעט לא עולה כלום כשלא נזרקת חריגה, והקומפיילרים הגדולים של C++ לא מוסיפים עלות בזמן ריצה למסלול שבו שום דבר לא נזרק. זריקה ותפיסה של חריגה איטיות בהרבה מבדיקת if, ולכן בלולאות שהביצועים בהן קריטיים, בדקו מקרים נפוצים במקום להסתמך על חריגות.