טיפול בשגיאות SDK ב-Go ושחזור משימות שנקטעו

מאת solvethree4 דקות קריאה

חריגה ממגבלת הזמן אינה אומרת שיצירת המשימה נכשלה. שמרו את קלטי המשימה המקוריים ואת מזהה הבקשה של ה-SDK. אם יש לכם מזהה משימה, המשיכו באמצעות GetTask; אחרת, הפעילו שוב את CreateTask עם הקלטים המקוריים המדויקים ועם אותו מזהה בקשה.

הביטול מפסיק את ההמתנה של לקוח Go, לא את המשימה המרוחקת. שחזרו את המשימה הזו לפני שתשלמו על פתרון חדש.

בדף הזה

הרצת הדוגמה לטיפול בשגיאות

השתמשו ב-Go 1.22 ומעלה עם המודול הרשמי solvethree.com/sdk, בגרסה v0.1.0. להגדרה, ראו את הוראות האינטגרציה עם Go.

הגדירו בצד השרת את משתני הסביבה SOLVETHREE_API_KEY ו-SOLVETHREE_PROXY. החליפו את Site ואת Action שבדוגמה בשם המארח ובפעולה של היעד שלכם. האתר זקוק לפרופיל פעיל בסביבת העבודה שלכם; שליחת שם המארח שלו אינה יוצרת פרופיל. בקשת reCAPTCHA הזו משתמשת בפרוקסי יחיד ואינה זקוקה ל-Type או ל-URL.

Go · בדיקת שגיאות ושמירת מזהי שחזור
package main

import (
    "context"
    "fmt"
    "errors"
    "log"
    "os"
    "time"
    solvethree "solvethree.com/sdk"
)

func main() {
    client, err := solvethree.NewClient(os.Getenv("SOLVETHREE_API_KEY"), nil)
    if err != nil { log.Fatal(err) }
    ctx, cancel := context.WithTimeout(context.Background(), 180*time.Second)
    defer cancel()
    input := solvethree.TaskRequest{Site: "accounts.example.com", Action: "login", Proxy: os.Getenv("SOLVETHREE_PROXY")}
    result, err := client.Solve(ctx, input, solvethree.SolveOptions{})
    if err != nil {
        var failed *solvethree.TaskFailedError
        var api *solvethree.APIError
        var recovery *solvethree.Error
        switch {
        case errors.As(err, &failed):
            log.Printf("Failed task %s: %s", failed.TaskID, failed.ErrorCode)
        case errors.As(err, &recovery):
            log.Printf("Recovery request=%s task=%s", recovery.RequestID, recovery.TaskID)
            if errors.As(err, &api) { log.Printf("HTTP %d; retry delay %s", api.StatusCode, api.RetryAfter) }
            // Save input plus recovery.RequestID. Resume GetTask for a known TaskID;
            // otherwise replay CreateTask with identical inputs and that RequestID.
        }
        return
    }
    fmt.Println("Ready task:", result.ID)
    // Submit result.Solution.Token with its browser identity and original proxy.
}

הדוגמה מגדירה ל-context מגבלת זמן של 180 שניות ורושמת ביומן מזהים לשחזור כאשר שגיאת SDK חושפת אותם. רישום ביומן אינו שחזור עמיד: שמרו את ה-input המקורי, את ה-RequestID שהוחזר וכל TaskID לפני שתשליכו את השגיאה.

״משימה מוכנה״ פירושה שיש פתרון זמין, לא שהיעד קיבל אותו. ה-SDK אינו שולח אותו עבורכם. שלחו את Solution.Token באמצעות זהות הדפדפן שהוחזרה, ובדוגמה הזו, שמשתמשת בפרוקסי יחיד, באמצעות הפרוקסי המקורי.

הבחנה בין משימה שנכשלה לבקשה שנקטעה

בדקו שגיאות עטופות באמצעות errors.As וביטול באמצעות errors.Is. הבדיקות האלה עונות על שאלות שונות: שגיאה אחת יכולה להכיל מזהים לשחזור, לעטוף שגיאת HTTP, ועדיין לדרוש טיפול כפעולה שנקטעה.

מה כל שגיאה אומרת
מה כל שגיאה אומרת
בדיקהמשמעות והפעולה הבאה
errors.As עבור *solvethree.TaskFailedErrorהמשימה הגיעה לכישלון סופי. קראו את TaskID, את RequestID ואת ErrorCode. אחזרו את המשימה שנכשלה באמצעות GetTask כדי לקבל את הטקסט שב-Error שלה, ואז הפסיקו לתשאל אותה. אל תשלחו שוב באופן עיוור קלטים שלא השתנו.
errors.Is עבור context.DeadlineExceeded או context.Canceledהקוד הקורא הפסיק להמתין. אין בכך כדי לקבוע אם היצירה הצליחה או אם המשימה המרוחקת הסתיימה. שמרו את פרטי השחזור והמשיכו עם context חדש כשמתאים.
errors.As עבור *solvethree.Errorמעטפת ה-SDK חושפת את RequestID ואת TaskID ועוטפת את ה-Cause שבבסיסה. שמרו את המזהים לצד הקלטים המקוריים המדויקים.
errors.As עבור *solvethree.APIErrorבדקו את StatusCode של HTTP ואת משך הזמן ב-RetryAfter. שגיאת HTTP שונה ממשימה שהסטטוס שלה הוא failed; אל תניחו שקיבלתם נתוני משימה בתגובה מוצלחת.

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

Solve יוצר את המשימה פעם אחת. הוא מנסה מחדש רק תשאולים שהחזירו תגובות זמניות עם HTTP 429, 502, 503 או 504, תוך כיבוד Retry-After במסגרת מגבלת הזמן של ה-context. CreateTask לעולם אינו מנסה שוב אוטומטית את בקשת ה-POST שלו.

המשיכו את המשימה הקיימת

  1. 1.

    שמירה על הבקשה המקורית ללא שינוי

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

  2. 2.

    שימוש ב-GetTask כשמזהה המשימה ידוע

    צרו context חדש אם תוקפו של הישן פג או שהוא בוטל, ואז אחזרו את ה-TaskID השמור באמצעות GetTask. המשיכו להמתין במצבים pending או solving, השתמשו בפתרון רק במצב ready, ועצרו במצב failed.

  3. 3.

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

    הגדירו את RequestID ב-TaskRequest המקורי ששמרתם למזהה הבקשה ששוחזר, ואז קראו ל-CreateTask עם אותם קלטים. שימוש חוזר באותו מזהה ובאותה בקשה מחזיר את המשימה הקיימת. שינוי הקלטים תוך שימוש חוזר באותו מזהה גורם להתנגשות.

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

הפעלת המשימה הראשונה שלך.

התחילו עם $5 בקרדיט לסביבת העבודה.

יצירת סביבת עבודה
טיפול בשגיאות SDK ב-Go ושחזור משימות שנקטעו · solvethree