פרק 7
איתור ותיקון באגים אוטומטי
באגים הם לא סימן שעשיתם משהו לא בסדר. הם חלק רגיל מכל פרויקט, גם אצל המפתחים הכי מנוסים בעולם. ההבדל בין מתחיל למקצוען הוא לא כמה באגים יש, אלא כמה מהר מוצאים ומתקנים אותם.
כאן Claude Code באמת זורח. הוא יודע לקרוא הודעות שגיאה מפחידות, לעקוב אחרי הבעיה דרך כמה קבצים, למצוא את המקור ולתקן אותו. התפקיד שלכם: לתת לו את הרמזים הנכונים, לוודא שהוא מתקן את הבעיה ולא רק מסתיר אותה, ולדעת לחזור אחורה כשמשהו לא הצליח.
אנטומיה של הודעת שגיאה
הודעת שגיאה נראית כמו ג'יבריש, אבל יש לה מבנה קבוע. הנה שגיאה טיפוסית מפרויקט Next.js:
TypeError: Cannot read properties of undefined (reading 'map')
at RecipePage (app/recipes/[slug]/page.tsx:24:38)
at renderWithHooks (node_modules/react-dom/cjs/react-dom-server.js:1523:18)
at renderElement (node_modules/react-dom/cjs/react-dom-server.js:2104:9)| חלק | בדוגמה | מה הוא אומר |
|---|---|---|
| סוג השגיאה | TypeError | איזו קטגוריה של בעיה. TypeError אומר בדרך כלל "ניסיתי להשתמש במשהו שהוא לא מה שחשבתי" |
| ההודעה | Cannot read properties of undefined (reading 'map') | מה קרה: ניסו להריץ map על משהו שלא קיים (undefined) |
| המיקום | page.tsx:24:38 | הקובץ, השורה (24) והתו (38) שבהם זה קרה |
| מחסנית הקריאות (Stack Trace) | כל שורות ה-at | המסלול שהקוד עבר עד שנפל, מהמקום הכי קרוב לבעיה ועד הרחוק ביותר |
שלב 1: מעבירים את השגיאה ל-Claude
דוח באג טוב
לפני שמדביקים, כדאי לחשוב רגע כמו בפרק 4. Claude צריך לדעת מה עשיתם, מה ציפיתם שיקרה, ומה קרה בפועל.
בקשה חלשה
זה לא עובד, תתקן
בקשה חזקה
כשאני נכנס לדף של מתכון שהוספתי דרך הטופס, הדף קורס. ציפיתי לראות את המתכון עם המצרכים. מתכונים ישנים עובדים רגיל. זה התחיל אחרי שהוספנו את טופס ההוספה. זו השגיאה מהטרמינל: [הדבקה של כל השגיאה]
תבנית להעתקה:
מה עשיתי: [הפעולה]. מה ציפיתי שיקרה: [התוצאה הרצויה]. מה קרה בפועל: [מה ראיתי]. מה כן עובד: [דברים דומים שתקינים]. מאז מתי: [אחרי איזה שינוי]. השגיאה המלאה: [הדבקה]
ארבע דרכים להעביר שגיאה
1. העתק-הדבק. הכי פשוט: מסמנים את כל השגיאה בטרמינל או בדפדפן, מעתיקים ומדביקים ל-Claude. שגיאה של כמה שורות עוברת בהדבקה אחת.
2. מריצים את הפקודה בתוך Claude Code, עם !. במקום להריץ בחלון אחר ולהעתיק, מריצים ישירות בשיחה. הפלט, כולל השגיאות, נכנס לשיחה, ו-Claude רואה הכול:
! npm run buildואחרי שהפלט מופיע, פשוט כותבים:
הבנייה נכשלה. תסביר לי מה השגיאה אומרת ותמצא את הסיבה
3. מעבירים פלט ישירות מהטרמינל. אם עוד לא נכנסתם ל-Claude Code, אפשר להעביר אליו פלט של פקודה. 2>&1 מוודא שגם השגיאות עוברות, ולא רק הפלט הרגיל:
npm run build 2>&1 | claude -p "תסביר בעברית פשוטה למה הבנייה נכשלה ומה צריך לתקן"npm run build 2>&1 | claude -p "תסביר בעברית פשוטה למה הבנייה נכשלה ומה צריך לתקן"npm run build 2>&1 | claude -p "תסביר בעברית פשוטה למה הבנייה נכשלה ומה צריך לתקן"4. צילום מסך. שגיאה שמופיעה בדפדפן, למשל חלון השגיאה האדום של Next.js או דף שנראה שבור, אפשר פשוט לצלם ולהדביק: Ctrl + V, וב-Windows Alt + V.
שלב 2: מוצאים את שורש הבעיה
סימפטום מול סיבה
כשיש לכם חום, אפשר לקחת אקמול, והחום ירד. אבל אם יש דלקת, היא עדיין שם. גם בקוד: המקום שבו השגיאה מופיעה הוא לא תמיד המקום שבו הבעיה נמצאת.
בדוגמה שלנו, השגיאה מופיעה ב-page.tsx, בשורה שמציגה את המצרכים:
<ul>
{recipe.ingredients.map((item) => (
<li key={item.name}>{item.amount} {item.unit} {item.name}</li>
))}
</ul>הקוד הזה תקין לגמרי. הבעיה נמצאת בקובץ אחר: הטופס להוספת מתכון שומר את המצרכים תחת שם אחר:
const newRecipe = {
title: formData.get("title"),
slug: makeSlug(formData.get("title")),
ingredientsList: parseIngredients(formData.get("ingredients")), // ← השם לא תואם
steps: parseSteps(formData.get("steps")),
};מתכונים מהטופס נשמרים עם ingredientsList, ודף המתכון מחפש ingredients. אצלו, השדה פשוט לא קיים, כלומר undefined, ומשם הקריסה.
שימו לב: כדי למצוא את זה צריך לעקוב אחרי הנתונים דרך כמה קבצים: הטופס, קובץ השמירה, קובץ ה-JSON ודף המתכון. זה בדיוק מה ש-Claude עושה טוב, אם מבקשים ממנו.
מבקשים חקירה, לא תיקון
בקשה חלשה
תתקן את השגיאה ב-page.tsx
בקשה חזקה
יש קריסה בדף המתכון, רק במתכונים שנוספו מהטופס. אל תתקן עדיין. תעקוב אחרי הנתונים של מתכון כזה מהרגע שהטופס נשלח, דרך השמירה, ועד שהדף מציג אותם. תגיד לי איפה בדיוק הנתונים משתנים או הולכים לאיבוד, ומה שורש הבעיה.
עוד טכניקות חקירה
היפותזות מדורגות. כשהבעיה לא ברורה, בקשו מ-Claude לחשוב כמו בלש:
תציע שלוש סיבות אפשריות לבעיה, מהסבירה ביותר לפחות סבירה. לכל אחת: איך נבדוק אם היא נכונה, בלי לשנות קוד
מה השתנה? אם משהו עבד אתמול ולא עובד היום, התשובה נמצאת כמעט תמיד בשינויים האחרונים. כאן Git (פרק 8) משתלם:
הדף הזה עבד בשמירה של אתמול ונשבר מאז. תשווה את הקוד הנוכחי לשמירות האחרונות ב-git, ותגיד לי איזה שינוי הכי סביר שגרם לבעיה
הדפסות זמניות. לפעמים צריך לראות מה קורה בזמן ריצה:
תוסיף הדפסות זמניות (console.log) במקומות המרכזיים בדרך של הנתונים, כדי שנראה איפה הם משתנים. תסמן כל הדפסה בהערה TEMP-DEBUG, כדי שיהיה קל למחוק את כולן אחרי שנמצא את הבעיה
חקירה בפרויקט גדול. אם צריך לחפש בהרבה קבצים, אפשר לבקש מ-Claude להשתמש בסוכני משנה (Subagents). הם קוראים את הקבצים בחלון הקשר נפרד ומחזירים רק את המסקנות, כך שהשיחה הראשית לא מתמלאת:
תשתמש בסוכני משנה כדי לחקור את כל המקומות בפרויקט שבהם נשמרים או נקראים מתכונים, ותחזיר לי רשימה של כל שמות השדות שבשימוש בכל מקום
שלב 3: מתקנים ומוודאים
תיקון אמיתי מול טיוח
אחרי שהבנתם את שורש הבעיה, מבקשים תיקון, ומקפידים שהוא יטפל בסיבה:
עכשיו תתקן את שורש הבעיה: תאחד את שם השדה כך שהטופס ישמור ingredients, כמו כל שאר המתכונים. תתקן גם מתכונים שכבר נשמרו בשם הישן בקובץ ה-JSON. בנוסף, תוסיף לדף המתכון הודעה ידידותית אם למתכון אין מצרכים בכלל, במקום קריסה
- ingredientsList: parseIngredients(formData.get("ingredients")),
+ ingredients: parseIngredients(formData.get("ingredients")),הכי פשוט לכתוב את זה מראש בבקשה:
בקשה חלשה
תגרום לשגיאה להיעלם
בקשה חזקה
תתקן את שורש הבעיה. אל תסתיר את השגיאה עם try/catch, ts-ignore או בדיקות שמדלגות על המקרה. אם אתה חושב שאין ברירה אלא לעקוף, תעצור ותסביר לי למה.
קודם משחזרים, אחר כך מתקנים
הדרך הכי בטוחה לדעת שבאג תוקן: לראות אותו קורה, לתקן, ולראות שהוא כבר לא קורה.
לפני שאתה מתקן, תכתוב בדיקה (Test) קטנה שמשחזרת את הבאג ונכשלת. אחר כך תתקן, ותריץ את הבדיקה שוב כדי להראות שהיא עוברת. תראה לי את הפלט של שתי ההרצות
אם בפרויקט אין עדיין בדיקות אוטומטיות, אפשר לבקש גרסה פשוטה יותר:
תכתוב לי רשימה של צעדים מדויקים לשחזר את הבאג בדפדפן. אני אוודא שהוא קורה, ואחרי התיקון אבדוק שוב לפי אותם צעדים
כלל השניים
אם Claude ניסה לתקן פעמיים ועדיין לא הצליח, אל תמשיכו לבקש "תנסה שוב". השיחה כבר מלאה בניסיונות כושלים, והם מבלבלים אותו. במקום זה:
- חזרו אחורה לפני הניסיונות הכושלים (בחלק הבא).
- הריצו
/clear. - כתבו בקשה חדשה שכוללת את מה שלמדתם: "כבר ניסינו X ו-Y וזה לא עבד, כי Z".
שלב 4: כשהתיקון הזיק, חוזרים אחורה
לפעמים "תיקון" שובר משהו אחר, או ש-Claude שינה יותר ממה שביקשתם. אין בעיה: יש כמה דרכים לחזור אחורה, לכל מצב הדרך שלו.
עצירה מיידית: Esc
רואים ש-Claude הולך לכיוון לא נכון? Esc אחד עוצר אותו מיד. השיחה נשמרת, ואפשר להסביר לו מה לעשות אחרת.
חזרה בזמן: /rewind
Claude Code שומר נקודת ביקורת (Checkpoint) לפני כל הודעה שאתם שולחים, כולל עותק של הקבצים שהוא עומד לשנות. כדי לחזור:
/rewindאו לחיצה כפולה על Esc. ייפתח תפריט של ההודעות הקודמות שלכם. בוחרים את הנקודה שאליה רוצים לחזור, ואז בוחרים מה להחזיר:
| אפשרות | מה קורה | מתי להשתמש |
|---|---|---|
| קוד ושיחה | גם הקבצים וגם השיחה חוזרים לנקודה שבחרתם | ה"תיקון" היה טעות מוחלטת, ורוצים להתחיל מחדש מאותה נקודה |
| רק קוד | הקבצים חוזרים, השיחה נשארת | רוצים לבטל את השינויים, אבל ש-Claude יזכור מה ניסה ולמה זה לא עבד |
| רק שיחה | השיחה חוזרת, הקבצים נשארים | הקוד בסדר, אבל השיחה הסתבכה וצריך להתחיל ממנה מחדש |
| סיכום מנקודה זו | ההודעות מהנקודה הזאת מסוכמות | השיחה ארוכה, ורוצים לפנות מקום בלי לאבד את מה שהיה |
חזרה עם Git
Git הוא רשת הביטחון החזקה ביותר, כי הוא שומר את כל מצב הפרויקט ולא משנה מי שינה אותו. אם שמרתם נקודת ביטחון לפני שהתחלתם לתקן (פרק 8), אתם תמיד יכולים לחזור אליה.
ביטול שינויים שעוד לא נשמרו בקובץ מסוים:
תראה לי מה השתנה ב-app/page.tsx מאז השמירה האחרונה ב-git. אם זה רק התיקון הכושל, תחזיר את הקובץ הזה בלבד למצב של השמירה האחרונה
git diff app/page.tsx
git restore app/page.tsxביטול שמירה שכבר נעשתה:
השמירה האחרונה ב-git שברה את החיפוש. תבטל אותה עם git revert, כך שתיווצר שמירה חדשה שמבטלת אותה, בלי למחוק היסטוריה
git log --oneline -3
git revert a3f9c21git revert לא מוחק את השמירה הבעייתית. הוא מוסיף שמירה חדשה שמבטלת אותה, ולכן הוא בטוח גם אחרי שהקוד כבר עלה ל-GitHub.
איזה כלי מתי?
| המצב | הכלי |
|---|---|
| Claude באמצע, והולך לכיוון לא נכון | Esc |
| Claude ערך קבצים בשיחה הזאת, והעריכה הזיקה | /rewind (או Esc פעמיים) |
| השינוי כולל פקודות טרמינל, או שעשיתם שינויים בעצמכם | Git: git restore לקובץ מסוים, אחרי בדיקת diff |
| השינוי כבר נשמר ב-git | git revert |
| השינוי כבר עלה ל-GitHub | git revert, ואז דחיפה רגילה. אף פעם לא force push (פרק 8) |
שלב 5: מקרי קצה, הבאגים שעוד לא קרו
מקרה קצה (Edge Case) הוא מצב לא שגרתי שהקוד לא תמיד מוכן אליו: שדה ריק, מספר אפס, טקסט ארוך מאוד, אינטרנט איטי. רוב הבאגים שמשתמשים אמיתיים מוצאים הם בדיוק כאלה. הדרך הכי טובה לטפל בהם: למצוא אותם לפני המשתמשים.
| סוג | דוגמה באתר המתכונים | מה עלול לקרות |
|---|---|---|
| ריק | חיפוש שמכיל רק רווחים | כל המתכונים נעלמים, או שאף אחד לא נעלם |
| אפס או שלילי | מחשבון מנות על 0 | חלוקה באפס, כמויות NaN |
| חסר | מתכון בלי אימוג'י או בלי שלבים | חור בעיצוב, או קריסה |
| ארוך מאוד | שם מתכון של 80 תווים | הטקסט חורג מהכרטיס |
| תווים מיוחדים | שם עם גרשיים: "פשטידת ג'ינג'ר" | שבירה בקישור או בחיפוש |
| עברית ואנגלית מעורבות | "עוגת Oreo של שירה" | סדר מילים הפוך |
| אחסון לא זמין | גלישה בחלון פרטי | המועדפים או סימון השלבים קורסים |
בקשה חלשה
תבדוק שאין באגים
בקשה חזקה
תעבור על פיצ'ר מחשבון המנות ותחשוב על מקרי קצה: ערכים ריקים, אפס, מספרים גדולים מאוד, כמויות עם שברים, ומצרכים בלי כמות (כמו ״מלח לפי הטעם״). לכל מקרה תגיד לי מה קורה היום, ואם זה בעייתי, תציע תיקון. עוד לא לתקן.
שלב 6: תיקון שגיאות בנייה (npm run build)
למה זה עובד ב-dev ונשבר ב-build?
npm run dev סלחני: הוא מריץ את האתר גם כשיש בעיות קטנות, כדי שתוכלו להמשיך לעבוד. npm run build מכין את הגרסה שתעלה לאוויר, והוא קפדני: הוא בודק את כל הקבצים, את הטיפוסים של TypeScript, ולפעמים גם מריץ בודק קוד (Lint). לכן לא נדיר שהאתר עובד מצוין ב-dev, ונכשל ב-build.
הכלל: מריצים npm run build לעתים קרובות, לא רק רגע לפני ההעלאה. ככה כל בעיה קטנה ופשוטה לתיקון.
השגיאות הנפוצות
שגיאת טיפוסים (Type error): הקוד מעביר ערך מסוג אחד למקום שמצפה לסוג אחר.
./components/ServingsCalculator.tsx:14:7
Type error: Type 'string' is not assignable to type 'number'.
12 | const [servings, setServings] = useState(recipe.servings);
13 | function onChange(e) {
> 14 | setServings(e.target.value);
| ^כאן הערך מתיבת הקלט הוא טקסט ("4"), והקוד מצפה למספר (4).
מודול לא נמצא (Module not found): קובץ או חבילה שהקוד מנסה לייבא לא קיימים, בדרך כלל בגלל שם שגוי, אות גדולה או קטנה, או חבילה שלא הותקנה.
Module not found: Can't resolve '@/components/recipeCard'(שימו לב: הקובץ נקרא RecipeCard, עם R גדולה. ב-Windows זה לפעמים עובד ב-dev, ונשבר רק בבנייה או בשרת.)
רכיב של צד הלקוח בלי הצהרה: קוד שמשתמש ביכולות של הדפדפן, כמו useState או לחיצות, בלי לסמן את הקובץ כ-Client Component:
You're importing a component that needs `useState`. This React Hook only works
in a Client Component. To fix, mark the file (or its parent) with the
`"use client"` directive.שגיאה ביצירת דף מראש (Prerender error): הבנייה מנסה ליצור דף מראש, ומשהו בו קורס. בדרך כלל זו בעיה בנתונים, כמו בדוגמת ingredients שראינו.
Error occurred prerendering page "/recipes/grandma-cheesecake".
TypeError: Cannot read properties of undefined (reading 'map')הלולאה: לבנות, לתקן, לחזור
תריץ npm run build. אם יש שגיאות, תתקן את שורש הבעיה של כל אחת, ותריץ שוב. תחזור על זה עד שהבנייה עוברת בלי שגיאות. אסור להשבית בדיקות כדי לעבור: בלי ts-ignore, בלי eslint-disable, ובלי לשנות הגדרות כדי להתעלם משגיאות. בסוף תראה לי את הפלט הסופי, ותסכם במשפט אחד כל תיקון שעשית
תרגיל: ציד באגים
בתרגיל הזה Claude יטמין באגים, ואתם תמצאו אותם בעזרתו, אבל בשיחה אחרת, בלי לדעת מה הוא עשה. עבדו על אתר המתכונים מפרק 6, או על כל פרויקט עם Git.
חלק א': הטמנה
- ודאו שכל העבודה שמורה ב-git ושהבנייה עוברת.
- בקשו מ-Claude:
תיצור ענף חדש בשם bug-hunt. בענף הזה תכניס בכוונה שלושה באגים שונים: אחד שגורם לקריסה בדף מסוים, אחד שגורם לתוצאה שגויה בלי שגיאה בכלל, ואחד שנראה רק במקרה קצה. אל תספר לי מה עשית ואיפה. תכתוב תיאור של הבאגים לקובץ BUGS-ANSWERS.md ותשמור את הכול ב-git
- אל תפתחו את BUGS-ANSWERS.md! הריצו
/clear, כדי ש-Claude "ישכח" מה הוא עשה.
חלק ב': ציד
- הריצו
npm run buildואתnpm run dev, ונסו את האתר כמו משתמשים. מצאתם משהו מוזר? - לכל באג: דוח באג טוב, חקירה במצב תכנון בלי לתקן, ורק אז תיקון של שורש הבעיה.
- התיקון של אחד הבאגים הזיק? תרגלו
/rewind. - בקשו מ-Claude לחפש מקרי קצה בפיצ'ר שבו נראה לכם שמסתתר הבאג השלישי.
חלק ג': בדיקה
- רק עכשיו פתחו את
BUGS-ANSWERS.mdוהשוו. - בקשו מ-Claude לחזור ל-main ולמחוק את הענף
bug-hunt. האתר המקורי לא נפגע, כי הכול קרה בענף נפרד.
סיימתם את התרגיל?
0 מתוך 8
סיכום
- מעבירים שגיאה בשלמותה: העתק-הדבק,
!בתוך Claude Code,2>&1 | claude -p, או צילום מסך. עם דוח באג: מה עשיתי, מה ציפיתי, מה קרה, מאז מתי. - קודם חקירה, אחר כך תיקון: מצב תכנון, מעקב אחרי הנתונים דרך כל הקבצים, היפותזות, ובדיקה מה השתנה ב-git.
- תיקון אמיתי, לא טיוח: בלי
try/catchשבולע, בליts-ignoreובלי לכבות בדיקות. משחזרים את הבאג, מתקנים, ומוודאים. - חזרה אחורה:
Escלעצירה,/rewindלעריכות של Claude,git restoreו-git revertלכל השאר. - מקרי קצה: ריק, אפס, חסר, ארוך, תווים מיוחדים. מוצאים אותם לפני המשתמשים.
- שגיאות בנייה: מריצים
npm run buildלעתים קרובות, ומתקנים בלולאה עד שעובר.
בפרק הבא נכיר את Git ו-GitHub לעומק: ענפים, Pull Requests, סקירת קוד וחגורות בטיחות שמגינות על הקוד שלכם.
בדקו את עצמכם
1. Claude 'תיקן' באג עם try/catch שבולע את השגיאה. מה הבעיה?
2. מה /rewind לא יכול לבטל?
פתרון כל שאלות החידון מסמן את הפרק כהושלם אוטומטית.