Trate erros do SDK de Go e recupere tarefas interrompidas
Um timeout não significa que a criação da tarefa falhou. Guarde os dados de entrada originais da tarefa e o ID de requisição do SDK. Se você tiver um ID de tarefa, retome com GetTask; caso contrário, repita CreateTask com os dados de entrada originais exatos e o mesmo ID de requisição.
O cancelamento faz o cliente Go parar de esperar, mas não interrompe a tarefa remota. Recupere essa tarefa antes de pagar por uma nova resolução.
Nesta página
Execute o exemplo de tratamento de erros
Use Go 1.22 ou posterior com o módulo oficial solvethree.com/sdk, versão v0.1.0. Consulte as instruções de integração com Go para configurar.
Defina as variáveis de ambiente SOLVETHREE_API_KEY e SOLVETHREE_PROXY no servidor. Substitua Site e Action do exemplo pelo hostname e pela ação do seu destino. O site precisa de um perfil ativo no seu workspace; enviar o hostname não cria um perfil. Esta requisição de reCAPTCHA usa um único proxy e não precisa de Type nem de 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.
}O exemplo define um prazo de 180 segundos para o contexto e registra IDs de recuperação no log quando um erro do SDK os expõe. O registro em log não é uma recuperação durável: salve o input original, o RequestID retornado e qualquer TaskID antes de descartar o erro.
“Tarefa pronta” significa que há uma solução disponível, não que o destino a aceitou. O SDK não faz o envio por você. Envie Solution.Token usando a identidade de navegador retornada e, neste exemplo com um único proxy, o proxy original.
Diferencie uma tarefa que falhou de uma requisição interrompida
Inspecione erros encapsulados com errors.As e o cancelamento com errors.Is. Essas verificações respondem a perguntas diferentes: um erro pode conter IDs de recuperação, encapsular um erro HTTP e ainda precisar ser tratado como uma operação interrompida.
| Verificação | Significado e próxima ação |
|---|---|
errors.As para *solvethree.TaskFailedError | A tarefa atingiu uma falha terminal. Leia TaskID, RequestID e ErrorCode. Consulte a tarefa que falhou com GetTask para obter o texto de Error e pare de consultar essa tarefa. Não reenvie cegamente os dados de entrada sem alterações. |
errors.Is para context.DeadlineExceeded ou context.Canceled | O chamador parou de esperar. Isso não determina se a criação foi bem-sucedida ou se a tarefa remota terminou. Retenha as informações de recuperação e retome com um novo contexto quando apropriado. |
errors.As para *solvethree.Error | O wrapper do SDK expõe RequestID e TaskID e encapsula a Cause subjacente. Salve os IDs junto com os dados de entrada originais exatos. |
errors.As para *solvethree.APIError | Inspecione o StatusCode HTTP e a duração de RetryAfter. Um erro HTTP é diferente de uma tarefa cujo status é failed; não presuma que você recebeu um payload de tarefa bem-sucedido. |
O exemplo verifica se há um APIError aninhado no ramo de recuperação. Verifique o cancelamento separadamente com errors.Is se a aplicação precisar distinguir o esgotamento do prazo de um cancelamento explícito.
Solve cria a tarefa uma vez. Ele repete apenas as consultas que recebem respostas temporárias com HTTP 429, 502, 503 ou 504, respeitando Retry-After dentro do prazo do contexto. CreateTask nunca repete seu POST automaticamente.
Retome a tarefa existente
- 1.
Mantenha a requisição original intacta
Salve todos os dados de entrada da tarefa, incluindo o proxy ou a lista de candidatos, junto com o ID da requisição. CreateTask gera um ID de requisição quando você o omite; capture o valor gerado exposto pelo erro de recuperação. Não reconstrua a requisição posteriormente a partir de uma configuração que pode ter mudado.
- 2.
Use GetTask quando souber o ID da tarefa
Crie um novo contexto se o anterior tiver expirado ou sido cancelado e consulte o TaskID salvo com GetTask. Continue aguardando nos estados pending ou solving, use a solução apenas no estado ready e pare no estado failed.
- 3.
Repita a criação apenas quando não souber o ID da tarefa
Defina RequestID no TaskRequest original salvo com o ID de requisição recuperado e chame CreateTask com os mesmos dados de entrada. Reutilizar o mesmo ID e a mesma requisição retorna a tarefa existente. Alterar os dados de entrada reutilizando esse ID causa um conflito.
Não use um novo ID de requisição só porque a conexão excedeu o tempo limite. Isso inicia uma nova tarefa lógica em vez de recuperar aquela cujo resultado é incerto. Primeiro, determine o que aconteceu com a tarefa original; se ela falhou, inspecione o erro antes de decidir se é necessária uma requisição corrigida.
Fontes e referência da API
Execute sua primeira tarefa.
Comece com $5 em créditos no espaço de trabalho.