שלטו בטיפול בשגיאות FastAPI עם מנהלי חריגים מותאמים אישית. למדו ליצור APIs חזקים עם תגובות שגיאה אלגנטיות לחוויית משתמש טובה יותר. שפרו את אמינות וקלות התחזוקה של האפליקציה שלכם.
טיפול בשגיאות בפייתון FastAPI: בניית מנהלי חריגים מותאמים אישית חזקים
טיפול בשגיאות הוא היבט קריטי בבניית APIs חזקים ואמינים. בפייתון FastAPI, ניתן למנף מנהלי חריגים מותאמים אישית לניהול אלגנטי של שגיאות ולמתן תגובות אינפורמטיביות ללקוחות. פוסט זה ידריך אתכם בתהליך יצירת מנהלי חריגים מותאמים אישית ב-FastAPI, ויאפשר לכם לבנות אפליקציות עמידות וידידותיות יותר למשתמש.
למה מנהלי חריגים מותאמים אישית?
FastAPI מספק תמיכה מובנית בטיפול בחריגים. עם זאת, הסתמכות בלעדית על תגובות שגיאה ברירת מחדל עלולה להשאיר את הלקוחות עם מידע מעורפל או לא מועיל. מנהלי חריגים מותאמים אישית מציעים מספר יתרונות:
- חוויית משתמש משופרת: ספקו הודעות שגיאה ברורות ואינפורמטיביות המותאמות לתרחישי שגיאה ספציפיים.
- ניהול שגיאות מרכזי: קבצו את לוגיקת הטיפול בשגיאות במקום אחד, מה שהופך את הקוד שלכם לקל יותר לתחזוקה.
- תגובות שגיאה עקביות: ודאו שתגובות השגיאה עוקבות אחר פורמט עקבי, מה שמשפר את השימושיות של ה-API.
- אבטחה משופרת: מנעו חשיפת מידע רגיש בהודעות שגיאה.
- רישום מותאם אישית: רשמו מידע שגיאה מפורט לצורך דיבוג וניטור.
הבנת הטיפול בחריגים של FastAPI
FastAPI משתמש בשילוב של מנגנוני הטיפול בחריגים המובנים של פייתון ומערכת הזרקת התלויות שלו לניהול שגיאות. כאשר חריג מועלה בתוך מסלול (route) או תלות (dependency), FastAPI מחפש מנהל חריגים מתאים כדי לעבד אותו.
מנהלי חריגים הם פונקציות המעוטרות ב-@app.exception_handler() ומקבלות שני ארגומנטים: סוג החריג ואובייקט הבקשה. המנהל אחראי להחזיר תגובת HTTP מתאימה.
יצירת חריגים מותאמים אישית
לפני הגדרת מנהלי חריגים מותאמים אישית, מועיל לעתים קרובות ליצור מחלקות חריגים מותאמות אישית המייצגות תנאי שגיאה ספציפיים באפליקציה שלכם. זה משפר את קריאות הקוד ומקל על הטיפול בסוגי שגיאות שונים.
לדוגמה, נניח שאתם בונים API למסחר אלקטרוני וצריכים לטפל במקרים שבהם מוצר אזל מהמלאי. ניתן להגדיר מחלקת חריג מותאמת אישית בשם OutOfStockError:
class OutOfStockError(Exception):
def __init__(self, product_id: int):
self.product_id = product_id
self.message = f"Product with ID {product_id} is out of stock."
מחלקה זו של חריג מותאם אישית יורשת ממחלקת Exception הבסיסית וכוללת תכונה product_id והודעת שגיאה מותאמת אישית.
יישום מנהלי חריגים מותאמים אישית
כעת, ניצור מנהל חריגים מותאם אישית עבור OutOfStockError. מנהל זה יתפוס את החריג ויחזיר תגובת HTTP 400 (בקשה לא תקינה) עם גוף JSON המכיל את הודעת השגיאה.
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
app = FastAPI()
class OutOfStockError(Exception):
def __init__(self, product_id: int):
self.product_id = product_id
self.message = f"Product with ID {product_id} is out of stock."
@app.exception_handler(OutOfStockError)
async def out_of_stock_exception_handler(request: Request, exc: OutOfStockError):
return JSONResponse(
status_code=400,
content={"message": exc.message},
)
@app.get("/products/{product_id}")
async def get_product(product_id: int):
# Simulate checking product stock
if product_id == 123:
raise OutOfStockError(product_id=product_id)
return {"product_id": product_id, "name": "Example Product", "price": 29.99}
בדוגמה זו, הקישוט @app.exception_handler(OutOfStockError) רושם את הפונקציה out_of_stock_exception_handler לטיפול בחריגי OutOfStockError. כאשר OutOfStockError מועלה במסלול get_product, מנהל החריגים מופעל. המנהל מחזיר אז JSONResponse עם קוד סטטוס 400 וגוף JSON המכיל את הודעת השגיאה.
טיפול במספר סוגי חריגים
ניתן להגדיר מנהלי חריגים מרובים לטיפול בסוגי חריגים שונים. לדוגמה, ייתכן שתרצו לטפל בחריגי ValueError המתרחשים בעת ניתוח קלט משתמש.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
app = FastAPI()
@app.exception_handler(ValueError)
async def value_error_exception_handler(request: Request, exc: ValueError):
return JSONResponse(
status_code=400,
content={"message": str(exc)},
)
@app.get("/items/{item_id}")
async def get_item(item_id: int):
# Simulate invalid item_id
if item_id < 0:
raise ValueError("Item ID must be a positive integer.")
return {"item_id": item_id, "name": "Example Item"}
בדוגמה זו, הפונקציה value_error_exception_handler מטפלת בחריגי ValueError. היא מחלצת את הודעת השגיאה מאובייקט החריג ומחזירה אותה בתגובת JSON.
שימוש ב-HTTPException
FastAPI מספק מחלקת חריג מובנית בשם HTTPException שניתן להשתמש בה להעלאת שגיאות ספציפיות ל-HTTP. זה יכול להיות שימושי לטיפול בתרחישי שגיאה נפוצים כגון גישה לא מורשית או משאב שלא נמצא.
from fastapi import FastAPI, HTTPException
app = FastAPI()
@app.get("/users/{user_id}")
async def get_user(user_id: int):
# Simulate user not found
if user_id == 999:
raise HTTPException(status_code=404, detail="User not found")
return {"user_id": user_id, "name": "Example User"}
בדוגמה זו, HTTPException מועלה עם קוד סטטוס 404 (לא נמצא) והודעת פירוט. FastAPI מטפל אוטומטית בחריגי HTTPException ומחזיר תגובת JSON עם קוד הסטטוס והפירוט שצוינו.
מנהלי חריגים גלובליים
ניתן גם להגדיר מנהלי חריגים גלובליים שתופסים את כל החריגים שאינם מטופלים. זה יכול להיות שימושי לרישום שגיאות או להחזרת הודעת שגיאה כללית ללקוח.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import logging
app = FastAPI()
logger = logging.getLogger(__name__)
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
logger.exception(f"Unhandled exception: {exc}")
return JSONResponse(
status_code=500,
content={"message": "Internal server error"},
)
@app.get("/error")
async def trigger_error():
raise ValueError("This is a test error.")
בדוגמה זו, הפונקציה global_exception_handler מטפלת בכל החריגים שאינם מטופלים על ידי מנהלי חריגים אחרים. היא רושמת את השגיאה ומחזירה תגובת 500 (שגיאה פנימית בשרת) עם הודעת שגיאה כללית.
שימוש ב-Middleware לטיפול בחריגים
גישה נוספת לטיפול בחריגים היא שימוש ב-middleware. פונקציות Middleware מבוצעות לפני ואחרי כל בקשה, ומאפשרות לכם ליירט ולטפל בחריגים ברמה גבוהה יותר. זה יכול להיות שימושי למשימות כמו רישום בקשות ותגובות, או ליישום לוגיקת אימות או הרשאה מותאמת אישית.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import logging
app = FastAPI()
logger = logging.getLogger(__name__)
@app.middleware("http")
async def exception_middleware(request: Request, call_next):
try:
response = await call_next(request)
except Exception as exc:
logger.exception(f"Unhandled exception: {exc}")
return JSONResponse(
status_code=500,
content={"message": "Internal server error"},
)
return response
@app.get("/error")
async def trigger_error():
raise ValueError("This is a test error.")
בדוגמה זו, הפונקציה exception_middleware עוטפת את לוגיקת עיבוד הבקשה בבלוק try...except. אם חריג מועלה במהלך עיבוד הבקשה, ה-middleware רושם את השגיאה ומחזיר תגובת 500 (שגיאה פנימית בשרת).
דוגמה: בינלאומיות (i18n) והודעות שגיאה
בעת בניית APIs עבור קהל גלובלי, שקלו בינלאומיות של הודעות השגיאה שלכם. זה כולל מתן הודעות שגיאה בשפות שונות בהתאם למיקום המשתמש. בעוד שהטמעת i18n מלאה היא מעבר להיקף המאמר הזה, הנה דוגמה פשוטה המדגימה את הקונספט:
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
from typing import Dict
app = FastAPI()
# Mock translation dictionary (replace with a real i18n library)
translations: Dict[str, Dict[str, str]] = {
"en": {
"product_not_found": "Product with ID {product_id} not found.",
"invalid_input": "Invalid input: {error_message}",
},
"fr": {
"product_not_found": "Produit avec l'ID {product_id} introuvable.",
"invalid_input": "Entrée invalide : {error_message}",
},
"es": {
"product_not_found": "Producto con ID {product_id} no encontrado.",
"invalid_input": "Entrada inválida: {error_message}",
},
"de": {
"product_not_found": "Produkt mit ID {product_id} nicht gefunden.",
"invalid_input": "Ungültige Eingabe: {error_message}",
}
}
def get_translation(locale: str, key: str, **kwargs) -> str:
"""Retrieves a translation for a given locale and key.
If the locale or key is not found, returns a default message.
"""
if locale in translations and key in translations[locale]:
return translations[locale][key].format(**kwargs)
return f"Translation missing for key '{key}' in locale '{locale}'."
@app.get("/products/{product_id}")
async def get_product(request: Request, product_id: int, locale: str = "en"):
# Simulate product lookup
if product_id > 100:
message = get_translation(locale, "product_not_found", product_id=product_id)
raise HTTPException(status_code=404, detail=message)
if product_id < 0:
message = get_translation(locale, "invalid_input", error_message="Product ID must be positive")
raise HTTPException(status_code=400, detail=message)
return {"product_id": product_id, "name": "Example Product"}
שיפורים עיקריים לדוגמת i18n:
- פרמטר Locale: המסלול מקבל כעת פרמטר שאילתה (query parameter)
locale, המאפשר ללקוחות לציין את השפה המועדפת עליהם (ברירת המחדל היא "en" לאנגלית). - מילון תרגומים: מילון
translations(mock) מאחסן הודעות שגיאה עבור locale שונים (אנגלית, צרפתית, ספרדית, גרמנית במקרה זה). באפליקציה אמיתית, תשתמשו בספריית i18n ייעודית. - פונקציית
get_translation: פונקציית עזר זו מאחזרת את התרגום המתאים בהתבסס עלlocaleו-key. היא גם תומכת בעיצוב מחרוזות כדי להכניס ערכים דינמיים (כמוproduct_id). - הודעות שגיאה דינמיות:
HTTPExceptionמועלה כעת עם הודעתdetailשנוצרת באופן דינמי באמצעות הפונקציהget_translation.
כאשר לקוח מבקש /products/101?locale=fr, הוא יקבל הודעת שגיאה בצרפתית (אם התרגום זמין). בעת בקשת /products/-1?locale=es, הוא יקבל הודעת שגיאה לגבי מזהה שלילי בספרדית (אם זמין). כאשר מבקשים /products/200?locale=xx (locale ללא תרגומים), הוא יקבל הודעת `Translation missing`.
שיטות עבודה מומלצות לטיפול בשגיאות
להלן מספר שיטות עבודה מומלצות שכדאי לקחת בחשבון בעת יישום טיפול בשגיאות ב-FastAPI:
- השתמשו בחריגים מותאמים אישית: הגדירו מחלקות חריגים מותאמות אישית לייצוג תנאי שגיאה ספציפיים באפליקציה שלכם.
- ספקו הודעות שגיאה אינפורמטיביות: כללו הודעות שגיאה ברורות ותמציתיות שיעזרו ללקוחות להבין את הסיבה לשגיאה.
- השתמשו בקוד סטטוס HTTP מתאים: החזירו קוד סטטוס HTTP המשקף במדויק את מהות השגיאה. לדוגמה, השתמשו ב-400 (בקשה לא תקינה) עבור קלט לא תקין, 404 (לא נמצא) עבור משאבים חסרים, ו-500 (שגיאה פנימית בשרת) עבור שגיאות בלתי צפויות.
- הימנעו מחשיפת מידע רגיש: היזהרו שלא לחשוף מידע רגיש כגון פרטי התחברות למסד נתונים או מפתחות API בהודעות שגיאה.
- רשמו שגיאות: רשמו מידע שגיאה מפורט לצורך דיבוג וניטור. השתמשו בספריית רישום כמו מודול
loggingהמובנה של פייתון. - רכזו את לוגיקת הטיפול בשגיאות: קבצו את לוגיקת הטיפול בשגיאות במקום אחד, כגון במנהלי חריגים מותאמים אישית או ב-middleware.
- בדקו את הטיפול בשגיאות שלכם: כתבו בדיקות יחידה (unit tests) כדי לוודא שלוגיקת הטיפול בשגיאות שלכם פועלת כראוי.
- שקלו להשתמש בשירות מעקב שגיאות ייעודי: עבור סביבות ייצור, שקלו להשתמש בשירות מעקב שגיאות ייעודי כמו Sentry או Rollbar כדי לנטר ולנתח שגיאות. כלים אלו יכולים לספק תובנות יקרות ערך לגבי בריאות האפליקציה שלכם ולעזור לכם לזהות ולפתור בעיות במהירות.
סיכום
מנהלי חריגים מותאמים אישית הם כלי עוצמתי לבניית APIs חזקים וידידותיים למשתמש ב-FastAPI. על ידי הגדרת מחלקות חריגים ומנהלים מותאמים אישית, ניתן לנהל שגיאות בצורה אלגנטית, לספק תגובות אינפורמטיביות ללקוחות, ולשפר את האמינות והתחזוקתיות הכוללת של האפליקציה שלכם. שילוב של חריגים מותאמים אישית, HTTPException, ומינוף עקרונות i18n במידת הצורך, ממצב את ה-API שלכם להצלחה גלובלית.
זכרו לשקול את חוויית המשתמש בעת תכנון אסטרטגיית הטיפול בשגיאות שלכם. ספקו הודעות שגיאה ברורות ותמציתיות שיעזרו למשתמשים להבין את הבעיה וכיצד לפתור אותה. טיפול יעיל בשגיאות הוא אבן פינה בבניית APIs באיכות גבוהה העונים על צרכיה של קהל גלובלי מגוון.