Connect with us

קטגוריות

Javascript

Javascript: טיפול בשגיאות בעזרת try/catch/finally

לא משנה עד כמה אתם מתכנתים טובים, לפעמים הקוד שלנו יכיל שגיאות, זה יכול להיות בעקבות טעות שעשינו, תגובה לא צפויה מהשרת, קלט לא צפוי מהמשתמש ועוד מליון ואחד סיבות. קוד טוב הוא קוד שמונע מראש מהשגיאות להקריס את המערכת ומטפל בה.

ב-Javascript, המנגנון הראשי לטיפול בשגיאות הוא תחביר ה-try/catch, בואו נביט על התחביר הבסיסי:

try {
  // כאן נמצא הקוד שאולי יזרוק שגיאה
} catch (e) {
  // כאן נמצא הקוד שירוץ במקרה של שגיאה
}

שימו לב שבלוק ה-catch מקבל גישה לאובייקט השגיאה (e) שמכיל שדות כמו name ו-message וברוב הדפדפנים יהיה שדה נוסף בשם stack שיכיל (ניחשתם נכון) את ה-stack trace שהוביל לשגיאה, הוא יופיע ברוב הדפדפנים מאחר והוא לא נמצא בסטנדרט.

מנקודה זו אתם יכולים לפתוח את ה-Console, להעתיק ולהדביק את קטעי הקוד שמופיעים על מנת להבין טוב יותר את הנאמר (לעצלנים צירפתי צילומי מסך).

בואו ניקח דוגמא שמכילה typo שיוביל לשגיאה:

try {
alertush("Meni")
} catch (e) {
  console.log('ooopsush: ', e);
}

במידה ונדביק את הקוד הזה ל-console נוכל לראות את השגיאה הבאה:

try/catch מטפל בשגיאות שמופיעות בזמן ריצה, במקרה של שגיאת תחביר (SyntaxError) תיזרק שגיאה בזמן הניתוח של הקוד (parse-time) וכתוצאה מכך האתר או התוכנית תקרוס ולא תעלה כלל, על מנת לטפל בשגיאות מהסוג הזה עוד בזמן הפיתוח השתמשו בלינטר (linter) כמו ESLint.

Just throw it

יהיו מקרים בהם מבחינתנו הייתה שגיאה, לדוגמא, נניח ופיתחתם חבילה שמכילה פונקציות עזר לחישוב אריתמטי, אחת הפונקציות שפיתחתם היא פונקציית subtraction שמקבלת שני ארגומנטים ומצפה ששניהם יהיו מסוג int על מנת לבצע את החיסור ללא הפתעות, מה יקרה אם למשל אחד מהארגומנטים שהפונקציה תקבל יהיה מחרוזת (string)? מבחינת Javascript אין פה בעיה מיוחדת, מבחינתנו יש שגיאה.

throw מעניק לנו את האפשרות ליזרוק את השגיאות, בואו נסתכל על הדוגמא הבאה:

(function subtraction(a, b){

    try {
        if(typeof a !== "number" || typeof b !== "number") throw new Error("Not a number!");

        return a - b;

    } catch(e){
        console.log(e)
    }

})(8, "2")

אחרי שנריץ את הקוד הבא אנחנו נקבל את השגיאה הבאה:

העברנו לפונקציה subtraction שני ארגומנטים שאחד מהם הוא מסוג מחרוזת (string), אחרי בדיקה קטנה, הבנו את זה והשתמשנו ב-throw ליזרוק את השגיאה ובקונסטרקטור Error על מנת ליצור אובייקט השגיאה עם הודעה (message) מיוחדת שאותה העברנו כארגומנט שבסופו של דבר יגיע לבלוק ה-catch שלנו.

במקרה הזה זרקנו שגיאה כללית והשדה name בתוך אובייקט השגיאה היה ״Error״ אך אנחנו יכולים לזרוק שגיאה ספציפית כמו TypeError, לדוגמא:

(function subtraction(a, b){

    try {
        if(typeof a !== "number" || typeof b !== "number") throw new TypeError("Not a number!");

        return a - b;

    } catch(e){
        console.log(e)
    }

})(8, "2")

סוף סוף finally

עד עכשיו השתמשנו ב try/catch על מנת לעטוף קוד ולהתגונן מפני שגיאות, אם יהיו כאלה הם יגיעו ל-catch ושם אנחנו נטפל בהם, בנוסף ל-try/catch יש את הבלוק finally שאיתו נוכל להבטיח שהקוד אשר נמצא בתוכו ירוץ לא משנה אם הייתה שגיאה או לא, לדוגמא:

(function subtraction(a, b){

    try {
        if(typeof a !== "number" || typeof b !== "number") throw new TypeError("Not a number!");

        return a - b;

    } catch(e){
        console.log(e)
    } finally {
		console.log("Wee wee")
	}

})(8, "2")

הערה: כשאנחנו משתמשים בבלוק ה-try, הבלוקים catch ו-finally הם אופציונלים, אנחנו יכולים לבחור להשתמש רק באחד מהם (או בשניהם).

בקוד הבא אנחנו נשתמש בבלוק ה-try ובבלוק ה-finally, מה יקרה אם תיהיה לנו שגיאה בתוך ה-try? השגיאה לא תטופל והתוכנית תקרוס, אך לא לפני שהקוד בבלוק ה-finally ירוץ.

(function subtraction(a, b){

    try {
        if(typeof a !== "number" || typeof b !== "number") throw new TypeError("Not a number!");

        return a - b;

    } finally {
		console.log("Wee wee")
	}

})(8, "2")
אם אתה חושב שיש מידע שהחסרתי או שיש דברים לא מדוייקים או לא מובנים במאמר, אשמח אם תאיר את עיניי באמצעות תגובה או דרך יצירת קשר בתפריט העליון.
תגובות

עוד ב Javascript

Meni Edri היי אני מני, מתכנת מנוסה ומאוד אוהב קוד ואת עולם התכנות, הקמתי את CodeHub על מנת שתיהיה לי פינה שבה אוכל לכתוב, ללמד וללמוד, מקווה שתימצאו את הבלוג הזה שימושי.
קריאה מהנה.

מאמרים פופולריים

נושאים פופולריים

חזרה למעלה