חיפוש ]

הצהרת throw ב- JavaScript: מדריך מפורט ודוגמאות קוד

הצהרת throw בג'אווה סקריפט משמשת ליצירת שגיאות מותאמות אישית. באמצעות throw ניתן ליצור exceptions ולטפל בהן באמצעות הצהרת try…catch, דבר המאפשר ניהול יעיל יותר וטיפול בשגיאות בצורה מבוקרת.

תחביר בסיסי – Syntax

התחביר הבסיסי של הצהרת throw נראה כך:

throw expression;

אל תשברו שורה בין מילת המפתח throw לביטוי. מנגנון ה-ASI (Automatic Semicolon Insertion) של JavaScript יתייחס לשבירת השורה כסוף ההצהרה, מה שיגרום ל-throw; שהיא שגיאת תחביר.

אותו expression יכול להיות כל ביטוי תקני ב-JavaScript, אבל תמיד כדאי לזרוק אובייקט Error (או תת-מחלקה שלו). זריקת מחרוזות או מספרים אפשרית טכנית אך מונעת גישה ל-stack trace ומקשה על ניפוי שגיאות.

תמיד השתמשו ב-throw new Error('message') או תת-מחלקת Error מותאמת. זריקת מחרוזת פשוטה כמו throw 'something went wrong' לא מייצרת stack trace ולא ניתנת ללכידה לפי סוג.

דוגמה לשימוש ב-throw

הנה קוד JavaScript המדגים את השימוש בהצהרת throw:

function divide(a, b) {
    if (b === 0) {
        throw new Error('Division by zero is not allowed.');
    }
    return a / b;
}

try {
    console.log(divide(4, 2)); // Output: 2
    console.log(divide(4, 0)); // Throws error
} catch (error) {
    console.error(error.message); // Output: Division by zero is not allowed.
}

בדוגמה זו, אם הערך b הוא אפס, נזרקת שגיאה עם הודעה מותאמת אישית. הבלוק try…catch משמש לטיפול בשגיאה ולהצגת ההודעה.

שימוש ב-throw עם שגיאות מותאמות אישית

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

class ValidationError extends Error {
    constructor(message) {
        super(message);
        this.name = 'ValidationError';
    }
}

function validateAge(age) {
    if (age < 0 || age > 120) {
        throw new ValidationError('Invalid age value.');
    }
    return true;
}

try {
    validateAge(150); // Throws ValidationError
} catch (error) {
    if (error instanceof ValidationError) {
        console.error(error.message); // Output: Invalid age value.
    } else {
        console.error('Unknown error:', error);
    }
}

״השלכת״ שגיאות מחדש – Re-throwing Errors

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

function parseJSON(jsonString) {
    try {
        return JSON.parse(jsonString);
    } catch (error) {
        if (error instanceof SyntaxError) {
            console.error('JSON parsing error:', error.message);
            throw error; // Re-throw the error
        } else {
            throw new Error('Unknown error');
        }
    }
}

try {
    parseJSON('invalid JSON');
} catch (error) {
    console.error('Caught an error:', error.message);
}

שרשור שגיאות עם cause

ES2022 הציגה את המאפיין cause, שמאפשר לצרף את השגיאה המקורית בעת זריקת שגיאה חדשה. כך נשמר שרשור השגיאות המלא מבלי לאבד הקשר:

async function fetchUser(id) {
    try {
        const response = await fetch(`/api/users/${id}`);
        if (!response.ok) {
            throw new Error(`HTTP ${response.status}`);
        }
        return await response.json();
    } catch (error) {
        throw new Error('Failed to fetch user', { cause: error });
    }
}

try {
    await fetchUser(42);
} catch (error) {
    console.error(error.message);       // "Failed to fetch user"
    console.error(error.cause.message); // "HTTP 404" (the original error)
}

המאפיין cause נתמך בכל הדפדפנים המודרניים וב-Node.js 16.9+.

שיטות עבודה מומלצות

להלן שיטות עבודה מומלצות לשימוש יעיל בהצהרת throw:

  • תמיד זרקו אובייקטי Error: לעולם אל תזרקו מחרוזות או מספרים. אובייקטי Error מספקים .message, .name, .stack ואופציונלית .cause – כולם חיוניים לניפוי שגיאות.
  • כתבו הודעות תיאוריות: כתבו הודעות שגיאה שמסבירות מה השתבש, וכשאפשר, כללו את הערך הלא תקין או ההקשר.
  • צרו סוגי שגיאות מותאמים: הגדירו תת-מחלקות Error עבור תרחישים ספציפיים לתחום. כך הקוד הקורא יכול להשתמש ב-instanceof כדי לטפל בשגיאות שונות בצורה שונה.
  • השתמשו ב-try…catch: תמיד טפלו בשגיאות שנזרקו באמצעות בלוקי try...catch כדי למנוע קריסת האפליקציה.
  • השליכו מחדש עם הקשר: בעת לכידה והשלכה מחדש, השתמשו באפשרות cause כדי לשמר את השגיאה המקורית.
  • אל תלכדו בצורה גורפת: הימנעו מלכידת Error ברמה העליונה והתעלמות שקטה ממנו. תעדו את השגיאה או טפלו בה בצורה משמעותית.

שאלות נפוצות

שאלות נפוצות על הצהרת throw ב-JavaScript:

האם אפשר לזרוק מחרוזת במקום אובייקט Error?
טכנית כן, אבל לא מומלץ. זריקת מחרוזת כמו throw 'error' לא מייצרת stack trace, אין לה מאפיין .name, ואין תמיכה ב-.cause. תמיד זרקו new Error('message') או תת-מחלקת Error מותאמת.
מה ההבדל בין throw ל-return?
return יוצא מפונקציה ומעביר ערך לקוד הקורא. throw יוצא מפונקציה וקופץ לבלוק catch הקרוב ביותר ב-call stack. אם אין catch, התוכנית קורסת. השתמשו ב-throw עבור מצבים חריגים שהקוד הקורא חייב לטפל בהם, לא עבור זרימת שליטה רגילה.
איך throw עובד בתוך פונקציית async?
בתוך פונקציית async, throw דוחה את ה-Promise המוחזר. הקוד הקורא יכול ללכוד את השגיאה עם try...catch (בתוך פונקציית async אחרת) או עם .catch() על ה-Promise. ההתנהגות שקולה לקריאה ל-Promise.reject(new Error('message')).
מתי כדאי ליצור מחלקת Error מותאמת?
צרו מחלקת Error מותאמת כאשר האפליקציה צריכה להבחין בין סוגי שגיאות שונים ולטפל בהם אחרת. לדוגמה, ValidationError עשוי להפעיל הודעה למשתמש, בעוד ש-HttpError עשוי להפעיל ניסיון חוזר. אם Error גנרי עם הודעה תיאורית מספיק, אין צורך ליצור מחלקה מותאמת.
מהו המאפיין cause באובייקטי Error?
המאפיין cause (ES2022) מאפשר לשרשר שגיאות על ידי צירוף השגיאה המקורית לשגיאה חדשה: throw new Error('High-level message', { cause: originalError }). כך נשמר ההקשר המלא של השגיאה, מה שמקל על ניפוי שגיאות כשהן נלכדות ונזרקות מחדש במספר שכבות.

סיכום

הצהרת throw מאפשרת ליצור שגיאות מותאמות שמתפשטות במעלה ה-call stack עד שבלוק catch מטפל בהן. תמיד זרקו אובייקטי Error או תת-מחלקות מותאמות – לעולם לא מחרוזות או מספרים פשוטים.

הרחיבו את מחלקת Error כדי ליצור סוגי שגיאות ספציפיים לתחום שהקוד הקורא יכול לזהות באמצעות instanceof. השתמשו במאפיין cause (ES2022) כדי לשמר את השגיאה המקורית בעת השלכה מחדש.

היזהרו מ-Automatic Semicolon Insertion – לעולם אל תשברו שורה בין throw לביטוי.

דיון ותגובות
0 תגובות  ]

השאירו תגובה

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

Savvy WordPress Development official logo