Go SDK 오류 처리 및 중단된 작업 복구하기
시간 초과가 발생했다고 해서 태스크 생성이 실패한 것은 아닙니다. 원래 태스크 입력값과 SDK의 요청 ID를 보관하세요. 태스크 ID가 있다면 GetTask로 재개하고, 없다면 정확한 원래 입력값과 동일한 요청 ID로 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 오류가 복구 ID를 제공하면 이를 기록합니다. 로그만으로는 영속적인 복구가 보장되지 않습니다. 오류를 버리기 전에 원래 input, 반환된 RequestID, 그리고 확보한 TaskID를 저장하세요.
“준비된 태스크”는 솔루션을 사용할 수 있다는 뜻이지, 대상이 수락했다는 뜻은 아닙니다. SDK는 대신 제출해 주지 않습니다. 반환된 브라우저 식별 정보와, 이 단일 프록시 예제에서는 원래 프록시를 사용하여 Solution.Token을 제출하세요.
실패한 태스크와 중단된 요청 구분
래핑된 오류는 errors.As로, 취소 여부는 errors.Is로 확인하세요. 이 검사들은 서로 다른 사항을 확인합니다. 하나의 오류에 복구 ID가 포함되고 HTTP 오류가 래핑되어 있으면서도, 중단된 작업으로 처리해야 할 수 있습니다.
| 확인 항목 | 의미와 다음 조치 |
|---|---|
errors.As로 *solvethree.TaskFailedError 확인 | 태스크가 최종 실패 상태에 도달했습니다. TaskID, RequestID, ErrorCode를 확인하세요. GetTask로 실패한 태스크를 조회하여 Error 텍스트를 확인한 다음, 해당 태스크의 폴링을 중단하세요. 변경하지 않은 입력값을 무작정 다시 제출하지 마세요. |
errors.Is로 context.DeadlineExceeded 또는 context.Canceled 확인 | 호출자가 대기를 중단했습니다. 이것만으로는 생성이 성공했는지, 원격 태스크가 완료되었는지 알 수 없습니다. 복구 정보를 보관하고 필요할 때 새 컨텍스트로 재개하세요. |
errors.As로 *solvethree.Error 확인 | SDK 래퍼는 RequestID와 TaskID를 제공하고 내부 Cause를 래핑합니다. 정확한 원래 입력값과 함께 ID를 저장하세요. |
errors.As로 *solvethree.APIError 확인 | HTTP StatusCode와 RetryAfter 대기 시간을 확인하세요. HTTP 오류는 상태가 failed인 태스크와 다릅니다. 성공적인 태스크 페이로드를 받았다고 가정하지 마세요. |
이 예제는 복구 분기 안에서 중첩된 APIError를 확인합니다. 애플리케이션에서 제한 시간 초과와 명시적 취소를 구분해야 한다면 errors.Is로 취소 여부를 별도로 확인하세요.
Solve는 태스크를 한 번 생성합니다. HTTP 429, 502, 503 또는 504인 일시적 폴링 응답만 재시도하며, 컨텍스트 제한 시간 내에서 Retry-After를 준수합니다. CreateTask는 POST를 자동으로 재시도하지 않습니다.
기존 작업 재개
- 1.
원래 요청을 그대로 보관
프록시 또는 후보 목록을 포함한 모든 태스크 입력값을 요청 ID와 함께 저장하세요. CreateTask는 요청 ID를 생략하면 ID를 생성합니다. 복구 오류에서 제공하는 생성된 값을 확보하세요. 나중에 변경되었을 수 있는 설정으로 요청을 재구성하지 마세요.
- 2.
태스크 ID를 알고 있다면 GetTask 사용
기존 컨텍스트가 만료되었거나 취소되었다면 새 컨텍스트를 생성한 다음, 저장된 TaskID를 GetTask로 조회하세요. 대기 중이거나 풀이 중이면 계속 기다리고, 준비된 상태에서만 솔루션을 사용하며, 실패하면 중단하세요.
- 3.
태스크 ID를 모를 때만 생성 요청 다시 실행
저장한 원래 TaskRequest의 RequestID를 복구한 요청 ID로 설정한 다음, 동일한 입력값으로 CreateTask를 호출하세요. 동일한 ID와 요청을 재사용하면 기존 태스크가 반환됩니다. 해당 ID를 재사용하면서 입력값을 변경하면 충돌이 발생합니다.
연결 시간이 초과되었다는 이유만으로 새 요청 ID를 사용하지 마세요. 그러면 상태가 불확실한 태스크를 복구하는 대신 새로운 논리적 태스크를 시작하게 됩니다. 먼저 원래 태스크에 무슨 일이 있었는지 확인하세요. 실패했다면 수정된 요청이 필요한지 결정하기 전에 오류를 확인하세요.
출처 및 API 레퍼런스
첫 작업을 실행하세요.
워크스페이스 크레딧 $5로 시작하세요.