לדלג לתוכן

דפוסי טיפול בשגיאות ב-API - איך מחזירים שגיאה נכון

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

למה צריך פורמט שגיאה אחיד

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

בחירת קוד הסטטוס הנכון

קוד הסטטוס של HTTP הוא לא פרט טכני שולי, הוא חלק מהתקשורת עם הקליינט. שגיאות בטווח 4xx אומרות "אתה, הקליינט, עשית משהו לא נכון" - קלט חסר, בקשה לא מורשית, משאב שלא קיים. שגיאות בטווח 5xx אומרות "אנחנו, השרת, נכשלנו" - חריגה שלא טופלה, כשל בחיבור למסד נתונים. הבחירה הנכונה חשובה כי היא קובעת איך הקליינט אמור להגיב - שגיאת 4xx בדרך כלל אומרת שאין טעם לנסות שוב בלי לתקן משהו בבקשה, בעוד ששגיאת 5xx לפעמים כן שווה לנסות שוב אחרי רגע. החזרת קוד הצלחה עם שדה שאומר בגוף התשובה שהפעולה נכשלה, למרות שנראית נוחה, שוברת את כל ההיגיון הזה ומקשה על קליינטים לזהות שגיאה בכלל.

אסור לחשוף פרטים פנימיים

טעות מסוכנת נוספת היא להחזיר ללקוח את השגיאה הגולמית כפי שהיא נתפסה בקוד - stack trace מלא, הודעת שגיאה מדויקת ממסד הנתונים, או שם קובץ פנימי. זה לא רק לא מקצועי, זו גם בעיית אבטחה ממשית - פרטים כאלה חושפים מידע על המבנה הפנימי של המערכת שלכם, ולפעמים אפילו מסייעים לתוקף למצוא נקודת תורפה. הכלל צריך להיות פשוט - כלפי חוץ, הלקוח מקבל הודעה כללית וברורה, בלי פרטים טכניים. הפרטים המלאים, כולל ה-stack trace, נשמרים רק בלוגים הפנימיים של השרת, שם מי שצריך לחקור את הבעיה יכול למצוא אותם.

מרכזים את הטיפול בשגיאות במקום אחד

הדפוס הנפוץ, אבל הבעייתי, הוא לפזר בלוק try/catch בכל endpoint בנפרד, כל אחד עם ההיגיון שלו להחזרת תשובה. זה מוביל בדיוק לחוסר העקביות שדיברנו עליו קודם, וגם הופך כל שינוי קטן בפורמט השגיאה למשימה שדורשת לגעת בעשרות מקומות בקוד. הגישה הנכונה היא לרכז את הטיפול בשגיאות במקום אחד - middleware או handler גלובלי שתופס כל שגיאה שנזרקת באפליקציה, ממפה אותה לקוד סטטוס ולפורמט התגובה האחיד שקבעתם, ורושם אותה ללוג. כל שאר הקוד באפליקציה יכול פשוט לזרוק שגיאה ולסמוך על כך שהיא תטופל נכון במקום מרכזי אחד.

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

לסיכום

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

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

הצטרפו לקהילה בדיסקורד