Gestiona los errores del SDK de Go y recupera tareas interrumpidas

Por solvethree5 min de lectura

Un tiempo de espera agotado no significa que la creación de la tarea haya fallado. Conserva los datos de entrada originales de la tarea y el ID de solicitud del SDK. Si tienes un ID de tarea, reanuda con GetTask; de lo contrario, vuelve a ejecutar CreateTask con exactamente los mismos datos de entrada originales y el mismo ID de solicitud.

La cancelación hace que el cliente de Go deje de esperar, pero no detiene la tarea remota. Recupera esa tarea antes de pagar por una nueva resolución.

En esta página

Ejecuta el ejemplo de gestión de errores

Usa Go 1.22 o posterior con el módulo oficial solvethree.com/sdk, versión v0.1.0. Consulta las instrucciones de integración con Go para configurarlo.

Configura las variables de entorno SOLVETHREE_API_KEY y SOLVETHREE_PROXY en el servidor. Sustituye Site y Action del ejemplo por el nombre de host y la acción de destino. El sitio necesita un perfil activo en tu espacio de trabajo; enviar su nombre de host no crea uno. Esta solicitud de reCAPTCHA usa un único proxy y no necesita Type ni URL.

Go · inspeccionar errores y conservar los ID de recuperación
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.
}

El ejemplo establece un plazo de contexto de 180 segundos y registra los ID de recuperación cuando un error del SDK los expone. El registro no constituye un mecanismo de recuperación persistente: guarda el input original, el RequestID devuelto y cualquier TaskID antes de descartar el error.

«Tarea lista» significa que hay una solución disponible, no que el destino la haya aceptado. El SDK no la envía por ti. Envía Solution.Token usando la identidad del navegador devuelta y, para este ejemplo con un único proxy, el proxy original.

Distingue una tarea fallida de una solicitud interrumpida

Inspecciona los errores encapsulados con errors.As y la cancelación con errors.Is. Estas comprobaciones responden a preguntas distintas: un error puede contener ID de recuperación, encapsular un error HTTP y aun así requerir que se gestione como una operación interrumpida.

Qué indica cada error
Qué indica cada error
ComprobaciónSignificado y siguiente acción
errors.As para *solvethree.TaskFailedErrorLa tarea terminó con un fallo definitivo. Lee TaskID, RequestID y ErrorCode. Recupera la tarea fallida con GetTask para obtener su texto de Error y luego deja de consultar esa tarea. No vuelvas a enviar a ciegas los mismos datos de entrada.
errors.Is para context.DeadlineExceeded o context.CanceledEl código que hizo la llamada dejó de esperar. Esto no permite determinar si la creación se completó correctamente o si la tarea remota terminó. Conserva la información de recuperación y reanuda con un contexto nuevo cuando corresponda.
errors.As para *solvethree.ErrorEl error contenedor del SDK expone RequestID y TaskID y encapsula su Cause subyacente. Guarda los ID junto con los datos de entrada originales exactos.
errors.As para *solvethree.APIErrorInspecciona el código HTTP StatusCode y la duración RetryAfter. Un error HTTP es distinto de una tarea cuyo estado es failed; no des por hecho que has recibido los datos de una tarea en una respuesta correcta.

El ejemplo comprueba si hay un APIError anidado dentro de su rama de recuperación. Comprueba la cancelación por separado con errors.Is si tu aplicación necesita distinguir entre el vencimiento de un plazo y una cancelación explícita.

Solve crea la tarea una sola vez. Solo reintenta las respuestas temporales de consulta con HTTP 429, 502, 503 o 504, respetando Retry-After dentro del plazo del contexto. CreateTask nunca reintenta automáticamente su POST.

Retoma la tarea existente

  1. 1.

    Conserva intacta la solicitud original

    Guarda todos los datos de entrada de la tarea, incluido el proxy o la lista de candidatos, junto con el ID de solicitud. CreateTask genera un ID de solicitud cuando lo omites; captura el valor generado que expone el error de recuperación. No reconstruyas la solicitud más adelante a partir de una configuración que pueda haber cambiado.

  2. 2.

    Usa GetTask cuando conozcas el ID de tarea

    Crea un contexto nuevo si el anterior venció o se canceló y luego recupera el TaskID guardado con GetTask. Sigue esperando si el estado es pending o solving, utiliza la solución solo si es ready y detente si es failed.

  3. 3.

    Repite la creación solo cuando no conozcas el ID de tarea

    Asigna el ID de solicitud recuperado a RequestID en el TaskRequest original guardado y luego llama a CreateTask con esos mismos datos de entrada. Reutilizar el mismo ID y la misma solicitud devuelve la tarea existente. Cambiar los datos de entrada y reutilizar ese ID provoca un conflicto.

No uses un ID de solicitud nuevo solo porque se haya agotado el tiempo de espera de la conexión. Eso inicia una nueva tarea lógica en lugar de recuperar aquella cuyo estado se desconoce. Primero determina qué ocurrió con la tarea original; si falló, inspecciona su error antes de decidir si hace falta una solicitud corregida.

Ejecuta tu primera tarea.

Empieza con $5 de crédito en tu espacio de trabajo.

Crear un espacio de trabajo
Gestiona los errores del SDK de Go y recupera tareas interrumpidas · solvethree