معالجة أخطاء حزمة SDK لـ Go واسترداد المهام المنقطعة
انتهاء المهلة لا يعني فشل إنشاء المهمة. احتفظ بمدخلات المهمة الأصلية ومعرّف الطلب الخاص بـ SDK. إذا كان لديك معرّف مهمة، فاستأنف باستخدام GetTask؛ وإلا فأعِد استدعاء CreateTask بالمدخلات الأصلية نفسها تمامًا ومعرّف الطلب نفسه.
يوقف الإلغاء انتظار عميل Go، لا المهمة البعيدة. استعد تلك المهمة قبل الدفع مقابل حل جديد.
في هذه الصفحة
تشغيل مثال معالجة الأخطاء
استخدم Go 1.22 أو أحدث مع الوحدة الرسمية solvethree.com/sdk بالإصدار v0.1.0. راجع تعليمات التكامل مع Go للإعداد.
اضبط متغيرَي البيئة SOLVETHREE_API_KEY وSOLVETHREE_PROXY على الخادم. استبدل Site وAction في المثال باسم المضيف والإجراء المستهدفين. يحتاج الموقع إلى ملف تعريف نشط في مساحة عملك؛ إرسال اسم مضيفه لا ينشئ ملفًا. يستخدم طلب reCAPTCHA هذا وكيلًا واحدًا ولا يحتاج إلى Type أو URL.
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.
}يضبط المثال مهلة نهائية للسياق تبلغ 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 | توقّف المستدعي عن الانتظار. لا يحدد ذلك ما إذا كان الإنشاء قد نجح أو اكتملت المهمة البعيدة. احتفظ بمعلومات الاستعادة واستأنف بسياق جديد عند الاقتضاء. |
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 ضمن المهلة النهائية للسياق. لا تعيد CreateTask محاولة طلب POST تلقائيًا مطلقًا.
استأنف المهمة الحالية
- 1.
الاحتفاظ بالطلب الأصلي دون تغيير
احفظ جميع مدخلات المهمة، بما فيها الوكيل أو قائمة الوكلاء المرشحين، مع معرّف الطلب. تنشئ CreateTask معرّف طلب إذا لم تحدده؛ احفظ القيمة المُنشأة التي يتيحها خطأ الاستعادة. لا تُعِد تكوين الطلب لاحقًا من إعدادات ربما تغيّرت.
- 2.
استخدام GetTask عندما تعرف معرّف المهمة
أنشئ سياقًا جديدًا إذا انتهت صلاحية السياق القديم أو أُلغي، ثم استرجع TaskID المحفوظ باستخدام GetTask. واصل الانتظار في حالتي الانتظار أو الحل، واستخدم الحل فقط في حالة الجاهزية، وتوقّف في حالة الفشل.
- 3.
إعادة محاولة الإنشاء فقط عندما لا تعرف معرّف المهمة
اضبط RequestID في TaskRequest الأصلي المحفوظ على معرّف الطلب المستعاد، ثم استدعِ CreateTask بالمدخلات نفسها. تعيد إعادة استخدام المعرّف والطلب نفسيهما المهمة الموجودة. أما تغيير المدخلات مع إعادة استخدام ذلك المعرّف فيؤدي إلى تعارض.
لا تستخدم معرّف طلب جديدًا لمجرد انتهاء مهلة الاتصال. فهذا يبدأ مهمة منطقية جديدة بدلًا من استعادة المهمة التي لم تُحسم حالتها. حدّد أولًا ما حدث للمهمة الأصلية؛ وإذا فشلت، فافحص خطأها قبل تقرير ما إذا كنت بحاجة إلى طلب مصحح.
المصادر ومرجع API
شغّل مهمتك الأولى.
ابدأ برصيد قدره $5 في مساحة العمل.