Menu
Coddy logo textTech

חילוץ שגיאות באמצעות `errors.Is`

חלק מהיחידה לוגיקה וזרימת התוכנית במסלול ה-GO של Coddy. שיעור 40 מתוך 68.

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

הפונקציה errors.Is מקבלת שני פרמטרים: השגיאה שברצונך לבדוק ושגיאת היעד שאתה מחפש. היא מחזירה true אם שגיאת היעד נמצאת במקום כלשהו בשרשרת השגיאות:

var ErrNotFound = errors.New("not found")

wrappedErr := fmt.Errorf("failed to load user: %w", ErrNotFound)

if errors.Is(wrappedErr, ErrNotFound) {
    fmt.Println("This is a not found error")
}

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

challenge icon

אתגר

קל

בנה מערכת לניטור חיבור למסד נתונים שמשתמשת ב־errors.Is כדי לזהות שגיאות חיבור מסוימות בשרשראות שגיאות עטופות. האתגר הזה מדגים כיצד להשתמש ב־errors.Is כדי לזהות שגיאות sentinel גם כשהן נעטפו בהקשר נוסף דרך כמה שכבות של היישום.

תקבל שתי קלטים:

  • מחרוזת שמכילה פרטים על פעולת מסד הנתונים בפורמט "database_name,operation,error_type" (לדוגמה, "users_db,connect,connection_timeout")
  • מחרוזת שמכילה הקשר של היישום בפורמט "service_name,retry_count" (לדוגמה, "AuthService,3")

המשימה שלך היא:

  1. להגדיר שלוש שגיאות sentinel באמצעות errors.New():
    • ErrConnectionTimeout עם ההודעה "connection timeout"
    • ErrConnectionRefused עם ההודעה "connection refused"
    • ErrDatabaseNotFound עם ההודעה "database not found"
  2. לנתח את הקלט הראשון באמצעות פיצול לפי פסיקים, כדי לקבל את שם מסד הנתונים, הפעולה וסוג השגיאה
  3. לנתח את הקלט השני באמצעות פיצול לפי פסיקים, כדי לקבל את שם השירות ומספר הניסיונות החוזרים
  4. ליצור את השגיאה המקורית על סמך סוג השגיאה:
    • אם סוג השגיאה הוא "connection_timeout": להשתמש ב־ErrConnectionTimeout
    • אם סוג השגיאה הוא "connection_refused": להשתמש ב־ErrConnectionRefused
    • אם סוג השגיאה הוא "database_not_found": להשתמש ב־ErrDatabaseNotFound
    • לכל סוג שגיאה אחר: להשתמש ב־errors.New("unknown database error")
  5. ליצור שגיאה עטופה ברמת מסד הנתונים באמצעות fmt.Errorf עם %w: "failed to [operation] database [database_name]: %w"
  6. ליצור שגיאה עטופה ברמת השירות: "[service_name] database operation failed after [retry_count] retries: %w"
  7. להשתמש ב־errors.Is כדי לבדוק אם השגיאה העטופה הסופית תואמת לכל אחת משגיאות ה־sentinel, ולהציג את התוצאות:
    • "Checking for connection timeout: [true/false]"
    • "Checking for connection refused: [true/false]"
    • "Checking for database not found: [true/false]"
  8. להציג את שרשרת השגיאות:
    • "Error Chain:"
    • "Original: [original_error_message]"
    • "Database level: [database_level_error_message]"
    • "Service level: [service_level_error_message]"
  9. להציג את ניתוח השגיאה:
    • "Error Analysis:"
    • "Database: [database_name]"
    • "Operation: [operation]"
    • "Service: [service_name]"
    • "Retries: [retry_count]"
    • "Error type detected: [detected_error_type]" כאשר detected_error_type הוא אחד מהערכים "Connection Timeout", "Connection Refused", "Database Not Found" או "Unknown Error"

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

נסו בעצמכם

package main

import (
	"errors"
	"fmt"
	"strings"
)

func main() {
	// קראו את הקלט
	var dbOperation string
	var appContext string
	fmt.Scanln(&dbOperation)
	fmt.Scanln(&appContext)
	
	// נתחו את הקלטים
	dbParts := strings.Split(dbOperation, ",")
	databaseName := dbParts[0]
	operation := dbParts[1]
	errorType := dbParts[2]
	
	contextParts := strings.Split(appContext, ",")
	serviceName := contextParts[0]
	retryCount := contextParts[1]
	
	// TODO: כתבו את הקוד שלכם למטה
	// 1. הגדירו את שלוש שגיאות הסמן באמצעות errors.New()
	// 2. צרו את השגיאה המקורית לפי סוג השגיאה
	// 3. צרו שגיאה עטופה ברמת מסד הנתונים באמצעות fmt.Errorf עם %w
	// 4. צרו שגיאה עטופה ברמת השירות
	// 5. השתמשו ב-errors.Is כדי לבדוק כל אחת משגיאות הסמן
	// 6. הציגו את התוצאות ואת שרשרת השגיאות
	
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה לוגיקה וזרימת התוכנית

תרגלו בעצמכם: קומפיילר Go אונליין